Vendor import of clang release_40 branch r295380:

https://llvm.org/svn/llvm-project/cfe/branches/release_40@295380
This commit is contained in:
Dimitry Andric 2017-02-17 19:36:19 +00:00
parent 3bae525304
commit eb2854521a
14 changed files with 275 additions and 55 deletions

View File

@ -2258,16 +2258,13 @@ non-block type [*]_. Equivalent to the following code:
.. code-block:: objc
id objc_storeStrong(id *object, id value) {
value = [value retain];
void objc_storeStrong(id *object, id value) {
id oldValue = *object;
value = [value retain];
*object = value;
[oldValue release];
return value;
}
Always returns ``value``.
.. [*] This does not imply that a ``__strong`` object of block type is an
invalid argument to this function. Rather it implies that an ``objc_retain``
and not an ``objc_retainBlock`` operation will be emitted if the argument is

View File

@ -17,7 +17,7 @@ Written by the `LLVM Team <http://llvm.org/>`_
Introduction
============
This document contains the release notes for the Clang C/C++/Objective-C
This document contains the release notes for the Clang C/C++/Objective-C/OpenCL
frontend, part of the LLVM Compiler Infrastructure, release 4.0.0. Here we
describe the status of Clang in some detail, including major
improvements from the previous release and new feature work. For the
@ -139,7 +139,76 @@ Objective-C Language Changes in Clang
OpenCL C Language Changes in Clang
----------------------------------
...
**The following bugs in the OpenCL header have been fixed:**
* Added missing ``overloadable`` and ``convergent`` attributes.
* Removed some erroneous extra ``native_*`` functions.
**The following bugs in the generation of metadata have been fixed:**
* Corrected the SPIR version depending on the OpenCL version.
* Source level address spaces are taken from the SPIR specification.
* Image types now contain no access qualifier.
**The following bugs in the AMD target have been fixed:**
* Corrected the bitwidth of ``size_t`` and NULL pointer value with respect to
address spaces.
* Added ``cl_khr_subgroups``, ``cl_amd_media_ops`` and ``cl_amd_media_ops2``
extensions.
* Added ``cl-denorms-are-zero`` support.
* Changed address spaces for image objects to be ``constant``.
* Added little-endian.
**The following bugs in OpenCL 2.0 have been fixed:**
* Fixed pipe builtin function return type, added extra argument to generated
IR intrinsics to propagate size and alignment information of the pipe packed
type.
* Improved pipe type to accommodate access qualifiers.
* Added correct address space to the ObjC block generation and ``enqueue_kernel``
prototype.
* Improved handling of integer parameters of ``enqueue_kernel`` prototype. We
now allow ``size_t`` instead of ``int`` for specifying block parameter sizes.
* Allow using NULL (aka ``CLK_NULL_QUEUE``) with ``queue_t``.
**Improved the following diagnostics:**
* Disallow address spaces other than ``global`` for kernel pointer parameters.
* Correct the use of half type argument and pointer assignment with
dereferencing.
* Disallow variadic arguments in functions and blocks.
* Allow partial initializer for array and struct.
**Some changes to OpenCL extensions have been made:**
* Added ``cl_khr_mipmap_image``.
* Added ``-cl-ext`` flag to allow overwriting supported extensions otherwise
set by the target compiled for (Example: ``-cl-ext=-all,+cl_khr_fp16``).
* New types and functions can now be flexibly added to extensions using the
following pragmas instead of modifying the Clang source code:
.. code-block:: c
#pragma OPENCL EXTENSION the_new_extension_name : begin
// declare types and functions associated with the extension here
#pragma OPENCL EXTENSION the_new_extension_name : end
**Miscellaneous changes:**
* Fix ``__builtin_astype`` to cast between different address space objects.
* Allow using ``opencl_unroll_hint`` with earlier OpenCL versions than 2.0.
* Improved handling of floating point literal to default to single precision if
fp64 extension is not enabled.
* Refactor ``sampler_t`` implementation to simplify initializer representation
which is now handled as a compiler builtin function with an integer value
passed into it.
* Change fake address space map to use the SPIR convention.
* Added `the OpenCL manual
<https://clang.llvm.org/docs/UsersManual.html#opencl-features>`_ to Clang
documentation.
OpenMP Support in Clang
----------------------------------

View File

@ -2056,6 +2056,8 @@ can be given manually.
In this case the kernel code should contain ``#include <opencl-c.h>`` just as a
regular C include.
.. _opencl_cl_ext:
.. option:: -cl-ext
Disables support of OpenCL extensions. All OpenCL targets provide a list
@ -2177,6 +2179,41 @@ To enable modules for OpenCL:
$ clang -target spir-unknown-unknown -c -emit-llvm -Xclang -finclude-default-header -fmodules -fimplicit-module-maps -fmodules-cache-path=<path to the generated module> test.cl
OpenCL Extensions
-----------------
All of the ``cl_khr_*`` extensions from `the official OpenCL specification
<https://www.khronos.org/registry/OpenCL/sdk/2.0/docs/man/xhtml/EXTENSION.html>`_
up to and including version 2.0 are available and set per target depending on the
support available in the specific architecture.
It is possible to alter the default extensions setting per target using
``-cl-ext`` flag. (See :ref:`flags description <opencl_cl_ext>` for more details).
Vendor extensions can be added flexibly by declaring the list of types and
functions associated with each extensions enclosed within the following
compiler pragma directives:
.. code-block:: c
#pragma OPENCL EXTENSION the_new_extension_name : begin
// declare types and functions associated with the extension here
#pragma OPENCL EXTENSION the_new_extension_name : end
For example, parsing the following code adds ``my_t`` type and ``my_func``
function to the custom ``my_ext`` extension.
.. code-block:: c
#pragma OPENCL EXTENSION my_ext : begin
typedef struct{
int a;
}my_t;
void my_func(my_t);
#pragma OPENCL EXTENSION my_ext : end
Declaring the same types in different vendor extensions is disallowed.
OpenCL Metadata
---------------
@ -2215,7 +2252,7 @@ does not have any effect on the IR. For more details reffer to the specification
<https://www.khronos.org/registry/cl/specs/opencl-2.0-openclc.pdf#49>`_
opencl_hint_unroll
opencl_unroll_hint
^^^^^^^^^^^^^^^^^^
The implementation of this feature mirrors the unroll hint for C.

View File

@ -604,10 +604,12 @@ namespace {
/// gets a chance to look at it.
EM_PotentialConstantExpressionUnevaluated,
/// Evaluate as a constant expression. Continue evaluating if either:
/// - We find a MemberExpr with a base that can't be evaluated.
/// - We find a variable initialized with a call to a function that has
/// the alloc_size attribute on it.
/// Evaluate as a constant expression. In certain scenarios, if:
/// - we find a MemberExpr with a base that can't be evaluated, or
/// - we find a variable initialized with a call to a function that has
/// the alloc_size attribute on it
/// then we may consider evaluation to have succeeded.
///
/// In either case, the LValue returned shall have an invalid base; in the
/// former, the base will be the invalid MemberExpr, in the latter, the
/// base will be either the alloc_size CallExpr or a CastExpr wrapping
@ -890,10 +892,6 @@ namespace {
return KeepGoing;
}
bool allowInvalidBaseExpr() const {
return EvalMode == EM_OffsetFold;
}
class ArrayInitLoopIndex {
EvalInfo &Info;
uint64_t OuterIndex;
@ -1394,8 +1392,10 @@ static bool Evaluate(APValue &Result, EvalInfo &Info, const Expr *E);
static bool EvaluateInPlace(APValue &Result, EvalInfo &Info,
const LValue &This, const Expr *E,
bool AllowNonLiteralTypes = false);
static bool EvaluateLValue(const Expr *E, LValue &Result, EvalInfo &Info);
static bool EvaluatePointer(const Expr *E, LValue &Result, EvalInfo &Info);
static bool EvaluateLValue(const Expr *E, LValue &Result, EvalInfo &Info,
bool InvalidBaseOK = false);
static bool EvaluatePointer(const Expr *E, LValue &Result, EvalInfo &Info,
bool InvalidBaseOK = false);
static bool EvaluateMemberPointer(const Expr *E, MemberPtr &Result,
EvalInfo &Info);
static bool EvaluateTemporary(const Expr *E, LValue &Result, EvalInfo &Info);
@ -4803,6 +4803,7 @@ class LValueExprEvaluatorBase
: public ExprEvaluatorBase<Derived> {
protected:
LValue &Result;
bool InvalidBaseOK;
typedef LValueExprEvaluatorBase LValueExprEvaluatorBaseTy;
typedef ExprEvaluatorBase<Derived> ExprEvaluatorBaseTy;
@ -4811,9 +4812,14 @@ protected:
return true;
}
bool evaluatePointer(const Expr *E, LValue &Result) {
return EvaluatePointer(E, Result, this->Info, InvalidBaseOK);
}
public:
LValueExprEvaluatorBase(EvalInfo &Info, LValue &Result) :
ExprEvaluatorBaseTy(Info), Result(Result) {}
LValueExprEvaluatorBase(EvalInfo &Info, LValue &Result, bool InvalidBaseOK)
: ExprEvaluatorBaseTy(Info), Result(Result),
InvalidBaseOK(InvalidBaseOK) {}
bool Success(const APValue &V, const Expr *E) {
Result.setFrom(this->Info.Ctx, V);
@ -4825,7 +4831,7 @@ public:
QualType BaseTy;
bool EvalOK;
if (E->isArrow()) {
EvalOK = EvaluatePointer(E->getBase(), Result, this->Info);
EvalOK = evaluatePointer(E->getBase(), Result);
BaseTy = E->getBase()->getType()->castAs<PointerType>()->getPointeeType();
} else if (E->getBase()->isRValue()) {
assert(E->getBase()->getType()->isRecordType());
@ -4836,7 +4842,7 @@ public:
BaseTy = E->getBase()->getType();
}
if (!EvalOK) {
if (!this->Info.allowInvalidBaseExpr())
if (!InvalidBaseOK)
return false;
Result.setInvalid(E);
return true;
@ -4930,8 +4936,8 @@ namespace {
class LValueExprEvaluator
: public LValueExprEvaluatorBase<LValueExprEvaluator> {
public:
LValueExprEvaluator(EvalInfo &Info, LValue &Result) :
LValueExprEvaluatorBaseTy(Info, Result) {}
LValueExprEvaluator(EvalInfo &Info, LValue &Result, bool InvalidBaseOK) :
LValueExprEvaluatorBaseTy(Info, Result, InvalidBaseOK) {}
bool VisitVarDecl(const Expr *E, const VarDecl *VD);
bool VisitUnaryPreIncDec(const UnaryOperator *UO);
@ -4984,10 +4990,11 @@ public:
/// * function designators in C, and
/// * "extern void" objects
/// * @selector() expressions in Objective-C
static bool EvaluateLValue(const Expr *E, LValue &Result, EvalInfo &Info) {
static bool EvaluateLValue(const Expr *E, LValue &Result, EvalInfo &Info,
bool InvalidBaseOK) {
assert(E->isGLValue() || E->getType()->isFunctionType() ||
E->getType()->isVoidType() || isa<ObjCSelectorExpr>(E));
return LValueExprEvaluator(Info, Result).Visit(E);
return LValueExprEvaluator(Info, Result, InvalidBaseOK).Visit(E);
}
bool LValueExprEvaluator::VisitDeclRefExpr(const DeclRefExpr *E) {
@ -5148,7 +5155,7 @@ bool LValueExprEvaluator::VisitArraySubscriptExpr(const ArraySubscriptExpr *E) {
if (E->getBase()->getType()->isVectorType())
return Error(E);
if (!EvaluatePointer(E->getBase(), Result, Info))
if (!evaluatePointer(E->getBase(), Result))
return false;
APSInt Index;
@ -5160,7 +5167,7 @@ bool LValueExprEvaluator::VisitArraySubscriptExpr(const ArraySubscriptExpr *E) {
}
bool LValueExprEvaluator::VisitUnaryDeref(const UnaryOperator *E) {
return EvaluatePointer(E->getSubExpr(), Result, Info);
return evaluatePointer(E->getSubExpr(), Result);
}
bool LValueExprEvaluator::VisitUnaryReal(const UnaryOperator *E) {
@ -5308,7 +5315,7 @@ static bool getBytesReturnedByAllocSizeCall(const ASTContext &Ctx,
/// and mark Result's Base as invalid.
static bool evaluateLValueAsAllocSize(EvalInfo &Info, APValue::LValueBase Base,
LValue &Result) {
if (!Info.allowInvalidBaseExpr() || Base.isNull())
if (Base.isNull())
return false;
// Because we do no form of static analysis, we only support const variables.
@ -5342,17 +5349,27 @@ namespace {
class PointerExprEvaluator
: public ExprEvaluatorBase<PointerExprEvaluator> {
LValue &Result;
bool InvalidBaseOK;
bool Success(const Expr *E) {
Result.set(E);
return true;
}
bool evaluateLValue(const Expr *E, LValue &Result) {
return EvaluateLValue(E, Result, Info, InvalidBaseOK);
}
bool evaluatePointer(const Expr *E, LValue &Result) {
return EvaluatePointer(E, Result, Info, InvalidBaseOK);
}
bool visitNonBuiltinCallExpr(const CallExpr *E);
public:
PointerExprEvaluator(EvalInfo &info, LValue &Result)
: ExprEvaluatorBaseTy(info), Result(Result) {}
PointerExprEvaluator(EvalInfo &info, LValue &Result, bool InvalidBaseOK)
: ExprEvaluatorBaseTy(info), Result(Result),
InvalidBaseOK(InvalidBaseOK) {}
bool Success(const APValue &V, const Expr *E) {
Result.setFrom(Info.Ctx, V);
@ -5399,9 +5416,10 @@ public:
};
} // end anonymous namespace
static bool EvaluatePointer(const Expr* E, LValue& Result, EvalInfo &Info) {
static bool EvaluatePointer(const Expr* E, LValue& Result, EvalInfo &Info,
bool InvalidBaseOK) {
assert(E->isRValue() && E->getType()->hasPointerRepresentation());
return PointerExprEvaluator(Info, Result).Visit(E);
return PointerExprEvaluator(Info, Result, InvalidBaseOK).Visit(E);
}
bool PointerExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
@ -5414,7 +5432,7 @@ bool PointerExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
if (IExp->getType()->isPointerType())
std::swap(PExp, IExp);
bool EvalPtrOK = EvaluatePointer(PExp, Result, Info);
bool EvalPtrOK = evaluatePointer(PExp, Result);
if (!EvalPtrOK && !Info.noteFailure())
return false;
@ -5432,7 +5450,7 @@ bool PointerExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
}
bool PointerExprEvaluator::VisitUnaryAddrOf(const UnaryOperator *E) {
return EvaluateLValue(E->getSubExpr(), Result, Info);
return evaluateLValue(E->getSubExpr(), Result);
}
bool PointerExprEvaluator::VisitCastExpr(const CastExpr* E) {
@ -5466,7 +5484,7 @@ bool PointerExprEvaluator::VisitCastExpr(const CastExpr* E) {
case CK_DerivedToBase:
case CK_UncheckedDerivedToBase:
if (!EvaluatePointer(E->getSubExpr(), Result, Info))
if (!evaluatePointer(E->getSubExpr(), Result))
return false;
if (!Result.Base && Result.Offset.isZero())
return true;
@ -5513,7 +5531,7 @@ bool PointerExprEvaluator::VisitCastExpr(const CastExpr* E) {
}
case CK_ArrayToPointerDecay:
if (SubExpr->isGLValue()) {
if (!EvaluateLValue(SubExpr, Result, Info))
if (!evaluateLValue(SubExpr, Result))
return false;
} else {
Result.set(SubExpr, Info.CurrentCall->Index);
@ -5530,18 +5548,19 @@ bool PointerExprEvaluator::VisitCastExpr(const CastExpr* E) {
return true;
case CK_FunctionToPointerDecay:
return EvaluateLValue(SubExpr, Result, Info);
return evaluateLValue(SubExpr, Result);
case CK_LValueToRValue: {
LValue LVal;
if (!EvaluateLValue(E->getSubExpr(), LVal, Info))
if (!evaluateLValue(E->getSubExpr(), LVal))
return false;
APValue RVal;
// Note, we use the subexpression's type in order to retain cv-qualifiers.
if (!handleLValueToRValueConversion(Info, E, E->getSubExpr()->getType(),
LVal, RVal))
return evaluateLValueAsAllocSize(Info, LVal.Base, Result);
return InvalidBaseOK &&
evaluateLValueAsAllocSize(Info, LVal.Base, Result);
return Success(RVal, E);
}
}
@ -5586,7 +5605,7 @@ bool PointerExprEvaluator::visitNonBuiltinCallExpr(const CallExpr *E) {
if (ExprEvaluatorBaseTy::VisitCallExpr(E))
return true;
if (!(Info.allowInvalidBaseExpr() && getAllocSizeAttr(E)))
if (!(InvalidBaseOK && getAllocSizeAttr(E)))
return false;
Result.setInvalid(E);
@ -5609,12 +5628,12 @@ bool PointerExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
unsigned BuiltinOp) {
switch (BuiltinOp) {
case Builtin::BI__builtin_addressof:
return EvaluateLValue(E->getArg(0), Result, Info);
return evaluateLValue(E->getArg(0), Result);
case Builtin::BI__builtin_assume_aligned: {
// We need to be very careful here because: if the pointer does not have the
// asserted alignment, then the behavior is undefined, and undefined
// behavior is non-constant.
if (!EvaluatePointer(E->getArg(0), Result, Info))
if (!evaluatePointer(E->getArg(0), Result))
return false;
LValue OffsetResult(Result);
@ -6255,7 +6274,7 @@ class TemporaryExprEvaluator
: public LValueExprEvaluatorBase<TemporaryExprEvaluator> {
public:
TemporaryExprEvaluator(EvalInfo &Info, LValue &Result) :
LValueExprEvaluatorBaseTy(Info, Result) {}
LValueExprEvaluatorBaseTy(Info, Result, false) {}
/// Visit an expression which constructs the value of this temporary.
bool VisitConstructExpr(const Expr *E) {
@ -7358,7 +7377,8 @@ static bool tryEvaluateBuiltinObjectSize(const Expr *E, unsigned Type,
if (!EvaluateAsRValue(Info, E, RVal))
return false;
LVal.setFrom(Info.Ctx, RVal);
} else if (!EvaluatePointer(ignorePointerCastsAndParens(E), LVal, Info))
} else if (!EvaluatePointer(ignorePointerCastsAndParens(E), LVal, Info,
/*InvalidBaseOK=*/true))
return false;
}

View File

@ -166,7 +166,7 @@ struct ObjCEntrypoints {
/// void objc_release(id);
llvm::Constant *objc_release;
/// id objc_storeStrong(id*, id);
/// void objc_storeStrong(id*, id);
llvm::Constant *objc_storeStrong;
/// id objc_storeWeak(id*, id);

View File

@ -2408,7 +2408,7 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr,
// fold-expressions, we'll need to allow multiple ArgExprs here.
if (ArgExprs.size() == 1 && isFoldOperator(Tok.getKind()) &&
NextToken().is(tok::ellipsis))
return ParseFoldExpression(Result, T);
return ParseFoldExpression(ArgExprs[0], T);
ExprType = SimpleExpr;
Result = Actions.ActOnParenListExpr(OpenLoc, Tok.getLocation(),

View File

@ -2831,6 +2831,9 @@ Sema::SpecialMemberOverloadResult *Sema::LookupSpecialMember(CXXRecordDecl *RD,
assert((SM != CXXDefaultConstructor && SM != CXXDestructor) &&
"parameter-less special members can't have qualified arguments");
// FIXME: Get the caller to pass in a location for the lookup.
SourceLocation LookupLoc = RD->getLocation();
llvm::FoldingSetNodeID ID;
ID.AddPointer(RD);
ID.AddInteger(SM);
@ -2912,7 +2915,7 @@ Sema::SpecialMemberOverloadResult *Sema::LookupSpecialMember(CXXRecordDecl *RD,
VK = VK_RValue;
}
OpaqueValueExpr FakeArg(SourceLocation(), ArgType, VK);
OpaqueValueExpr FakeArg(LookupLoc, ArgType, VK);
if (SM != CXXDefaultConstructor) {
NumArgs = 1;
@ -2926,13 +2929,13 @@ Sema::SpecialMemberOverloadResult *Sema::LookupSpecialMember(CXXRecordDecl *RD,
if (VolatileThis)
ThisTy.addVolatile();
Expr::Classification Classification =
OpaqueValueExpr(SourceLocation(), ThisTy,
OpaqueValueExpr(LookupLoc, ThisTy,
RValueThis ? VK_RValue : VK_LValue).Classify(Context);
// Now we perform lookup on the name we computed earlier and do overload
// resolution. Lookup is only performed directly into the class since there
// will always be a (possibly implicit) declaration to shadow any others.
OverloadCandidateSet OCS(RD->getLocation(), OverloadCandidateSet::CSK_Normal);
OverloadCandidateSet OCS(LookupLoc, OverloadCandidateSet::CSK_Normal);
DeclContext::lookup_result R = RD->lookup(Name);
if (R.empty()) {
@ -2987,7 +2990,7 @@ Sema::SpecialMemberOverloadResult *Sema::LookupSpecialMember(CXXRecordDecl *RD,
}
OverloadCandidateSet::iterator Best;
switch (OCS.BestViableFunction(*this, SourceLocation(), Best)) {
switch (OCS.BestViableFunction(*this, LookupLoc, Best)) {
case OR_Success:
Result->setMethod(cast<CXXMethodDecl>(Best->Function));
Result->setKind(SpecialMemberOverloadResult::Success);

View File

@ -2743,15 +2743,17 @@ bool Sema::isCopyElisionCandidate(QualType ReturnType, const VarDecl *VD,
// ...automatic...
if (!VD->hasLocalStorage()) return false;
// Return false if VD is a __block variable. We don't want to implicitly move
// out of a __block variable during a return because we cannot assume the
// variable will no longer be used.
if (VD->hasAttr<BlocksAttr>()) return false;
if (AllowParamOrMoveConstructible)
return true;
// ...non-volatile...
if (VD->getType().isVolatileQualified()) return false;
// __block variables can't be allocated in a way that permits NRVO.
if (VD->hasAttr<BlocksAttr>()) return false;
// Variables with higher required alignment than their type's ABI
// alignment cannot use NRVO.
if (!VD->getType()->isDependentType() && VD->hasAttr<AlignedAttr>() &&

View File

@ -1014,6 +1014,11 @@ ExprResult Sema::ActOnCXXFoldExpr(SourceLocation LParenLoc, Expr *LHS,
CheckFoldOperand(*this, LHS);
CheckFoldOperand(*this, RHS);
auto DiscardOperands = [&] {
CorrectDelayedTyposInExpr(LHS);
CorrectDelayedTyposInExpr(RHS);
};
// [expr.prim.fold]p3:
// In a binary fold, op1 and op2 shall be the same fold-operator, and
// either e1 shall contain an unexpanded parameter pack or e2 shall contain
@ -1021,6 +1026,7 @@ ExprResult Sema::ActOnCXXFoldExpr(SourceLocation LParenLoc, Expr *LHS,
if (LHS && RHS &&
LHS->containsUnexpandedParameterPack() ==
RHS->containsUnexpandedParameterPack()) {
DiscardOperands();
return Diag(EllipsisLoc,
LHS->containsUnexpandedParameterPack()
? diag::err_fold_expression_packs_both_sides
@ -1034,6 +1040,7 @@ ExprResult Sema::ActOnCXXFoldExpr(SourceLocation LParenLoc, Expr *LHS,
if (!LHS || !RHS) {
Expr *Pack = LHS ? LHS : RHS;
assert(Pack && "fold expression with neither LHS nor RHS");
DiscardOperands();
if (!Pack->containsUnexpandedParameterPack())
return Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs)
<< Pack->getSourceRange();

View File

@ -549,3 +549,22 @@ int incomplete_and_function_types() {
// CHECK: store i32 0
gi = __builtin_object_size(incomplete_char_array, 3);
}
// Flips between the pointer and lvalue evaluator a lot.
void deeply_nested() {
struct {
struct {
struct {
struct {
int e[2];
char f; // Inhibit our writing-off-the-end check
} d[2];
} c[2];
} b[2];
} *a;
// CHECK: store i32 4
gi = __builtin_object_size(&a->b[1].c[1].d[1].e[1], 1);
// CHECK: store i32 4
gi = __builtin_object_size(&a->b[1].c[1].d[1].e[1], 3);
}

View File

@ -34,3 +34,12 @@ template<int ...N> int bad9() { return (3 + ... * N); } // expected-error {{oper
template<int ...N> int bad10() { return (3 ? ... : N); } // expected-error +{{}} expected-note {{to match}}
template<int ...N> int bad11() { return (N + ... 0); } // expected-error {{expected a foldable binary operator}} expected-error {{expected expression}}
template<int ...N> int bad12() { return (... N); } // expected-error {{expected expression}}
template<typename ...T> void as_operand_of_cast(int a, T ...t) {
return
(int)(a + ... + undeclared_junk) + // expected-error {{undeclared}} expected-error {{does not contain any unexpanded}}
(int)(t + ... + undeclared_junk) + // expected-error {{undeclared}}
(int)(... + undeclared_junk) + // expected-error {{undeclared}} expected-error {{does not contain any unexpanded}}
(int)(undeclared_junk + ...) + // expected-error {{undeclared}}
(int)(a + ...); // expected-error {{does not contain any unexpanded}}
}

View File

@ -76,3 +76,18 @@ int pr28314(void) {
a += __builtin_object_size(p3->b, 0);
return a;
}
int pr31843() {
int n = 0;
struct { int f; } a;
int b;
n += __builtin_object_size(({&(b ? &a : &a)->f; pr31843;}), 0); // expected-warning{{expression result unused}}
struct statfs { char f_mntonname[1024];};
struct statfs *outStatFSBuf;
n += __builtin_object_size(outStatFSBuf->f_mntonname ? "" : "", 1); // expected-warning{{address of array}}
n += __builtin_object_size(outStatFSBuf->f_mntonname ?: "", 1);
return n;
}

View File

@ -105,3 +105,31 @@ namespace PR31606 {
// Note, we do *not* allow operator=='s argument to use the inherited A::A(Base&&) constructor to construct from B{}.
bool b = A{} == B{}; // expected-error {{invalid operands}}
}
namespace implicit_member_srcloc {
template<class T>
struct S3 {
};
template<class T>
struct S2 {
S2(S3<T> &&);
};
template<class T>
struct S1 : S2<T> {
using S2<T>::S2;
S1();
};
template<class T>
struct S0 {
S0();
S0(S0&&) = default;
S1<T> m1;
};
void foo1() {
S0<int> s0;
}
}

View File

@ -1,4 +1,4 @@
// RUN: %clang_cc1 -fsyntax-only -verify -fblocks -Wno-objc-root-class %s
// RUN: %clang_cc1 -fsyntax-only -verify -fblocks -Wno-objc-root-class -std=c++11 %s
@protocol NSObject;
void bar(id(^)(void));
@ -144,3 +144,17 @@ namespace DependentReturn {
template void f<X>(X);
}
namespace MoveBlockVariable {
struct B0 {
};
struct B1 { // expected-note 2 {{candidate constructor (the implicit}}
B1(B0&&); // expected-note {{candidate constructor not viable}}
};
B1 test_move() {
__block B0 b;
return b; // expected-error {{no viable conversion from returned value of type 'MoveBlockVariable::B0' to function return type 'MoveBlockVariable::B1'}}
}
}