summaryrefslogtreecommitdiff
path: root/lib/Sema/SemaExpr.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2019-01-19 10:04:05 +0000
committerDimitry Andric <dim@FreeBSD.org>2019-01-19 10:04:05 +0000
commit676fbe8105eeb6ff4bb2ed261cb212fcfdbe7b63 (patch)
tree02a1ac369cb734d0abfa5000dd86e5b7797e6a74 /lib/Sema/SemaExpr.cpp
parentc7e70c433efc6953dc3888b9fbf9f3512d7da2b0 (diff)
downloadsrc-test2-676fbe8105eeb6ff4bb2ed261cb212fcfdbe7b63.tar.gz
src-test2-676fbe8105eeb6ff4bb2ed261cb212fcfdbe7b63.zip
Notes
Diffstat (limited to 'lib/Sema/SemaExpr.cpp')
-rw-r--r--lib/Sema/SemaExpr.cpp1157
1 files changed, 749 insertions, 408 deletions
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 3dc6fb151cb7..d5416d4d057c 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -26,6 +26,7 @@
#include "clang/AST/ExprOpenMP.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/AST/TypeLoc.h"
+#include "clang/Basic/FixedPoint.h"
#include "clang/Basic/PartialDiagnostic.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/TargetInfo.h"
@@ -65,6 +66,12 @@ bool Sema::CanUseDecl(NamedDecl *D, bool TreatUnavailableAsInvalid) {
if (getLangOpts().CPlusPlus14 && FD->getReturnType()->isUndeducedType() &&
DeduceReturnType(FD, SourceLocation(), /*Diagnose*/ false))
return false;
+
+ // See if this is an aligned allocation/deallocation function that is
+ // unavailable.
+ if (TreatUnavailableAsInvalid &&
+ isUnavailableAlignedAllocationFunction(*FD))
+ return false;
}
// See if this function is unavailable.
@@ -114,7 +121,7 @@ void Sema::NoteDeletedFunction(FunctionDecl *Decl) {
return NoteDeletedInheritingConstructor(Ctor);
Diag(Decl->getLocation(), diag::note_availability_specified_here)
- << Decl << true;
+ << Decl << 1;
}
/// Determine whether a FunctionDecl was ever declared with an
@@ -205,7 +212,8 @@ void Sema::MaybeSuggestAddingStaticToDecl(const FunctionDecl *Cur) {
bool Sema::DiagnoseUseOfDecl(NamedDecl *D, ArrayRef<SourceLocation> Locs,
const ObjCInterfaceDecl *UnknownObjCClass,
bool ObjCPropertyAccess,
- bool AvoidPartialAvailabilityChecks) {
+ bool AvoidPartialAvailabilityChecks,
+ ObjCInterfaceDecl *ClassReceiver) {
SourceLocation Loc = Locs.front();
if (getLangOpts().CPlusPlus && isa<FunctionDecl>(D)) {
// If there were any diagnostics suppressed by template argument deduction,
@@ -226,6 +234,8 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, ArrayRef<SourceLocation> Locs,
// The function 'main' shall not be used within a program.
if (cast<FunctionDecl>(D)->isMain())
Diag(Loc, diag::ext_main_used);
+
+ diagnoseUnavailableAlignedAllocation(*cast<FunctionDecl>(D), Loc);
}
// See if this is an auto-typed variable whose initializer we are parsing.
@@ -264,6 +274,17 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, ArrayRef<SourceLocation> Locs,
return true;
}
+ if (auto *MD = dyn_cast<CXXMethodDecl>(D)) {
+ // Lambdas are only default-constructible or assignable in C++2a onwards.
+ if (MD->getParent()->isLambda() &&
+ ((isa<CXXConstructorDecl>(MD) &&
+ cast<CXXConstructorDecl>(MD)->isDefaultConstructor()) ||
+ MD->isCopyAssignmentOperator() || MD->isMoveAssignmentOperator())) {
+ Diag(Loc, diag::warn_cxx17_compat_lambda_def_ctor_assign)
+ << !isa<CXXConstructorDecl>(MD);
+ }
+ }
+
auto getReferencedObjCProp = [](const NamedDecl *D) ->
const ObjCPropertyDecl * {
if (const auto *MD = dyn_cast<ObjCMethodDecl>(D))
@@ -291,7 +312,7 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, ArrayRef<SourceLocation> Locs,
}
DiagnoseAvailabilityOfDecl(D, Locs, UnknownObjCClass, ObjCPropertyAccess,
- AvoidPartialAvailabilityChecks);
+ AvoidPartialAvailabilityChecks, ClassReceiver);
DiagnoseUnusedOfDecl(*this, D, Loc);
@@ -386,8 +407,7 @@ void Sema::DiagnoseSentinelCalls(NamedDecl *D, SourceLocation Loc,
// or 'NULL' if those are actually defined in the context. Only use
// 'nil' for ObjC methods, where it's much more likely that the
// variadic arguments form a list of object pointers.
- SourceLocation MissingNilLoc
- = getLocForEndOfToken(sentinelExpr->getLocEnd());
+ SourceLocation MissingNilLoc = getLocForEndOfToken(sentinelExpr->getEndLoc());
std::string NullValue;
if (calleeType == CT_Method && PP.isMacroDefined("nil"))
NullValue = "nil";
@@ -501,12 +521,13 @@ static void DiagnoseDirectIsaAccess(Sema &S, const ObjCIvarRefExpr *OIRE,
&S.Context.Idents.get("object_setClass"),
SourceLocation(), S.LookupOrdinaryName);
if (ObjectSetClass) {
- SourceLocation RHSLocEnd = S.getLocForEndOfToken(RHS->getLocEnd());
- S.Diag(OIRE->getExprLoc(), diag::warn_objc_isa_assign) <<
- FixItHint::CreateInsertion(OIRE->getLocStart(), "object_setClass(") <<
- FixItHint::CreateReplacement(SourceRange(OIRE->getOpLoc(),
- AssignLoc), ",") <<
- FixItHint::CreateInsertion(RHSLocEnd, ")");
+ SourceLocation RHSLocEnd = S.getLocForEndOfToken(RHS->getEndLoc());
+ S.Diag(OIRE->getExprLoc(), diag::warn_objc_isa_assign)
+ << FixItHint::CreateInsertion(OIRE->getBeginLoc(),
+ "object_setClass(")
+ << FixItHint::CreateReplacement(
+ SourceRange(OIRE->getOpLoc(), AssignLoc), ",")
+ << FixItHint::CreateInsertion(RHSLocEnd, ")");
}
else
S.Diag(OIRE->getLocation(), diag::warn_objc_isa_assign);
@@ -516,11 +537,11 @@ static void DiagnoseDirectIsaAccess(Sema &S, const ObjCIvarRefExpr *OIRE,
&S.Context.Idents.get("object_getClass"),
SourceLocation(), S.LookupOrdinaryName);
if (ObjectGetClass)
- S.Diag(OIRE->getExprLoc(), diag::warn_objc_isa_use) <<
- FixItHint::CreateInsertion(OIRE->getLocStart(), "object_getClass(") <<
- FixItHint::CreateReplacement(
- SourceRange(OIRE->getOpLoc(),
- OIRE->getLocEnd()), ")");
+ S.Diag(OIRE->getExprLoc(), diag::warn_objc_isa_use)
+ << FixItHint::CreateInsertion(OIRE->getBeginLoc(),
+ "object_getClass(")
+ << FixItHint::CreateReplacement(
+ SourceRange(OIRE->getOpLoc(), OIRE->getEndLoc()), ")");
else
S.Diag(OIRE->getLocation(), diag::warn_objc_isa_use);
}
@@ -575,10 +596,10 @@ ExprResult Sema::DefaultLvalueConversion(Expr *E) {
&Context.Idents.get("object_getClass"),
SourceLocation(), LookupOrdinaryName);
if (ObjectGetClass)
- Diag(E->getExprLoc(), diag::warn_objc_isa_use) <<
- FixItHint::CreateInsertion(OISA->getLocStart(), "object_getClass(") <<
- FixItHint::CreateReplacement(
- SourceRange(OISA->getOpLoc(), OISA->getIsaMemberLoc()), ")");
+ Diag(E->getExprLoc(), diag::warn_objc_isa_use)
+ << FixItHint::CreateInsertion(OISA->getBeginLoc(), "object_getClass(")
+ << FixItHint::CreateReplacement(
+ SourceRange(OISA->getOpLoc(), OISA->getIsaMemberLoc()), ")");
else
Diag(E->getExprLoc(), diag::warn_objc_isa_use);
}
@@ -717,20 +738,33 @@ ExprResult Sema::DefaultArgumentPromotion(Expr *E) {
return ExprError();
E = Res.get();
+ QualType ScalarTy = Ty;
+ unsigned NumElts = 0;
+ if (const ExtVectorType *VecTy = Ty->getAs<ExtVectorType>()) {
+ NumElts = VecTy->getNumElements();
+ ScalarTy = VecTy->getElementType();
+ }
+
// If this is a 'float' or '__fp16' (CVR qualified or typedef)
// promote to double.
// Note that default argument promotion applies only to float (and
// half/fp16); it does not apply to _Float16.
- const BuiltinType *BTy = Ty->getAs<BuiltinType>();
+ const BuiltinType *BTy = ScalarTy->getAs<BuiltinType>();
if (BTy && (BTy->getKind() == BuiltinType::Half ||
BTy->getKind() == BuiltinType::Float)) {
if (getLangOpts().OpenCL &&
!getOpenCLOptions().isEnabled("cl_khr_fp64")) {
- if (BTy->getKind() == BuiltinType::Half) {
- E = ImpCastExprToType(E, Context.FloatTy, CK_FloatingCast).get();
- }
+ if (BTy->getKind() == BuiltinType::Half) {
+ QualType Ty = Context.FloatTy;
+ if (NumElts != 0)
+ Ty = Context.getExtVectorType(Ty, NumElts);
+ E = ImpCastExprToType(E, Ty, CK_FloatingCast).get();
+ }
} else {
- E = ImpCastExprToType(E, Context.DoubleTy, CK_FloatingCast).get();
+ QualType Ty = Context.DoubleTy;
+ if (NumElts != 0)
+ Ty = Context.getExtVectorType(Ty, NumElts);
+ E = ImpCastExprToType(E, Ty, CK_FloatingCast).get();
}
}
@@ -819,40 +853,38 @@ void Sema::checkVariadicArgument(const Expr *E, VariadicCallType CT) {
switch (VAK) {
case VAK_ValidInCXX11:
DiagRuntimeBehavior(
- E->getLocStart(), nullptr,
- PDiag(diag::warn_cxx98_compat_pass_non_pod_arg_to_vararg)
- << Ty << CT);
+ E->getBeginLoc(), nullptr,
+ PDiag(diag::warn_cxx98_compat_pass_non_pod_arg_to_vararg) << Ty << CT);
LLVM_FALLTHROUGH;
case VAK_Valid:
if (Ty->isRecordType()) {
// This is unlikely to be what the user intended. If the class has a
// 'c_str' member function, the user probably meant to call that.
- DiagRuntimeBehavior(E->getLocStart(), nullptr,
+ DiagRuntimeBehavior(E->getBeginLoc(), nullptr,
PDiag(diag::warn_pass_class_arg_to_vararg)
- << Ty << CT << hasCStrMethod(E) << ".c_str()");
+ << Ty << CT << hasCStrMethod(E) << ".c_str()");
}
break;
case VAK_Undefined:
case VAK_MSVCUndefined:
- DiagRuntimeBehavior(
- E->getLocStart(), nullptr,
- PDiag(diag::warn_cannot_pass_non_pod_arg_to_vararg)
- << getLangOpts().CPlusPlus11 << Ty << CT);
+ DiagRuntimeBehavior(E->getBeginLoc(), nullptr,
+ PDiag(diag::warn_cannot_pass_non_pod_arg_to_vararg)
+ << getLangOpts().CPlusPlus11 << Ty << CT);
break;
case VAK_Invalid:
if (Ty.isDestructedType() == QualType::DK_nontrivial_c_struct)
- Diag(E->getLocStart(),
- diag::err_cannot_pass_non_trivial_c_struct_to_vararg) << Ty << CT;
+ Diag(E->getBeginLoc(),
+ diag::err_cannot_pass_non_trivial_c_struct_to_vararg)
+ << Ty << CT;
else if (Ty->isObjCObjectType())
- DiagRuntimeBehavior(
- E->getLocStart(), nullptr,
- PDiag(diag::err_cannot_pass_objc_interface_to_vararg)
- << Ty << CT);
+ DiagRuntimeBehavior(E->getBeginLoc(), nullptr,
+ PDiag(diag::err_cannot_pass_objc_interface_to_vararg)
+ << Ty << CT);
else
- Diag(E->getLocStart(), diag::err_cannot_pass_to_vararg)
- << isa<InitListExpr>(E) << Ty << CT;
+ Diag(E->getBeginLoc(), diag::err_cannot_pass_to_vararg)
+ << isa<InitListExpr>(E) << Ty << CT;
break;
}
}
@@ -890,20 +922,19 @@ ExprResult Sema::DefaultVariadicArgumentPromotion(Expr *E, VariadicCallType CT,
SourceLocation TemplateKWLoc;
UnqualifiedId Name;
Name.setIdentifier(PP.getIdentifierInfo("__builtin_trap"),
- E->getLocStart());
+ E->getBeginLoc());
ExprResult TrapFn = ActOnIdExpression(TUScope, SS, TemplateKWLoc,
Name, true, false);
if (TrapFn.isInvalid())
return ExprError();
- ExprResult Call = ActOnCallExpr(TUScope, TrapFn.get(),
- E->getLocStart(), None,
- E->getLocEnd());
+ ExprResult Call = ActOnCallExpr(TUScope, TrapFn.get(), E->getBeginLoc(),
+ None, E->getEndLoc());
if (Call.isInvalid())
return ExprError();
- ExprResult Comma = ActOnBinOp(TUScope, E->getLocStart(), tok::comma,
- Call.get(), E);
+ ExprResult Comma =
+ ActOnBinOp(TUScope, E->getBeginLoc(), tok::comma, Call.get(), E);
if (Comma.isInvalid())
return ExprError();
return Comma.get();
@@ -1436,9 +1467,9 @@ Sema::CreateGenericSelectionExpr(SourceLocation KeyLoc,
// We strip parens here because the controlling expression is typically
// parenthesized in macro definitions.
ControllingExpr = ControllingExpr->IgnoreParens();
- Diag(ControllingExpr->getLocStart(), diag::err_generic_sel_multi_match)
- << ControllingExpr->getSourceRange() << ControllingExpr->getType()
- << (unsigned) CompatIndices.size();
+ Diag(ControllingExpr->getBeginLoc(), diag::err_generic_sel_multi_match)
+ << ControllingExpr->getSourceRange() << ControllingExpr->getType()
+ << (unsigned)CompatIndices.size();
for (unsigned I : CompatIndices) {
Diag(Types[I]->getTypeLoc().getBeginLoc(),
diag::note_compat_assoc)
@@ -1455,8 +1486,8 @@ Sema::CreateGenericSelectionExpr(SourceLocation KeyLoc,
// We strip parens here because the controlling expression is typically
// parenthesized in macro definitions.
ControllingExpr = ControllingExpr->IgnoreParens();
- Diag(ControllingExpr->getLocStart(), diag::err_generic_sel_no_match)
- << ControllingExpr->getSourceRange() << ControllingExpr->getType();
+ Diag(ControllingExpr->getBeginLoc(), diag::err_generic_sel_no_match)
+ << ControllingExpr->getSourceRange() << ControllingExpr->getType();
return ExprError();
}
@@ -1549,6 +1580,32 @@ Sema::ActOnStringLiteral(ArrayRef<Token> StringToks, Scope *UDLScope) {
CharTy = Context.UnsignedCharTy;
}
+ // Warn on initializing an array of char from a u8 string literal; this
+ // becomes ill-formed in C++2a.
+ if (getLangOpts().CPlusPlus && !getLangOpts().CPlusPlus2a &&
+ !getLangOpts().Char8 && Kind == StringLiteral::UTF8) {
+ Diag(StringTokLocs.front(), diag::warn_cxx2a_compat_utf8_string);
+
+ // Create removals for all 'u8' prefixes in the string literal(s). This
+ // ensures C++2a compatibility (but may change the program behavior when
+ // built by non-Clang compilers for which the execution character set is
+ // not always UTF-8).
+ auto RemovalDiag = PDiag(diag::note_cxx2a_compat_utf8_string_remove_u8);
+ SourceLocation RemovalDiagLoc;
+ for (const Token &Tok : StringToks) {
+ if (Tok.getKind() == tok::utf8_string_literal) {
+ if (RemovalDiagLoc.isInvalid())
+ RemovalDiagLoc = Tok.getLocation();
+ RemovalDiag << FixItHint::CreateRemoval(CharSourceRange::getCharRange(
+ Tok.getLocation(),
+ Lexer::AdvanceToTokenCharacter(Tok.getLocation(), 2,
+ getSourceManager(), getLangOpts())));
+ }
+ }
+ Diag(RemovalDiagLoc, RemovalDiag);
+ }
+
+
QualType CharTyConst = CharTy;
// A C++ string literal has a const-qualified element type (C++ 2.13.4p1).
if (getLangOpts().CPlusPlus || getLangOpts().ConstStrings)
@@ -1681,7 +1738,7 @@ Sema::BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK,
if (getLangOpts().ObjCWeak && isa<VarDecl>(D) &&
Ty.getObjCLifetime() == Qualifiers::OCL_Weak && !isUnevaluatedContext() &&
- !Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, E->getLocStart()))
+ !Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, E->getBeginLoc()))
getCurFunction()->recordUseOfWeak(E);
FieldDecl *FD = dyn_cast<FieldDecl>(D);
@@ -2528,7 +2585,7 @@ Sema::PerformObjectMemberConversion(Expr *From,
if (Method->isStatic())
return From;
- DestType = Method->getThisType(Context);
+ DestType = Method->getThisType();
DestRecordType = DestType->getPointeeType();
if (FromType->getAs<PointerType>()) {
@@ -3026,7 +3083,7 @@ static void ConvertUTF8ToWideString(unsigned CharByteWidth, StringRef Source,
}
ExprResult Sema::BuildPredefinedExpr(SourceLocation Loc,
- PredefinedExpr::IdentType IT) {
+ PredefinedExpr::IdentKind IK) {
// Pick the current block, lambda, captured statement or function.
Decl *currentDecl = nullptr;
if (const BlockScopeInfo *BSI = getCurBlock())
@@ -3050,11 +3107,11 @@ ExprResult Sema::BuildPredefinedExpr(SourceLocation Loc,
else {
// Pre-defined identifiers are of type char[x], where x is the length of
// the string.
- auto Str = PredefinedExpr::ComputeName(IT, currentDecl);
+ auto Str = PredefinedExpr::ComputeName(IK, currentDecl);
unsigned Length = Str.length();
llvm::APInt LengthI(32, Length + 1);
- if (IT == PredefinedExpr::LFunction || IT == PredefinedExpr::LFuncSig) {
+ if (IK == PredefinedExpr::LFunction || IK == PredefinedExpr::LFuncSig) {
ResTy =
Context.adjustStringLiteralBaseType(Context.WideCharTy.withConst());
SmallString<32> RawChars;
@@ -3073,24 +3130,24 @@ ExprResult Sema::BuildPredefinedExpr(SourceLocation Loc,
}
}
- return new (Context) PredefinedExpr(Loc, ResTy, IT, SL);
+ return PredefinedExpr::Create(Context, Loc, ResTy, IK, SL);
}
ExprResult Sema::ActOnPredefinedExpr(SourceLocation Loc, tok::TokenKind Kind) {
- PredefinedExpr::IdentType IT;
+ PredefinedExpr::IdentKind IK;
switch (Kind) {
default: llvm_unreachable("Unknown simple primary expr!");
- case tok::kw___func__: IT = PredefinedExpr::Func; break; // [C99 6.4.2.2]
- case tok::kw___FUNCTION__: IT = PredefinedExpr::Function; break;
- case tok::kw___FUNCDNAME__: IT = PredefinedExpr::FuncDName; break; // [MS]
- case tok::kw___FUNCSIG__: IT = PredefinedExpr::FuncSig; break; // [MS]
- case tok::kw_L__FUNCTION__: IT = PredefinedExpr::LFunction; break; // [MS]
- case tok::kw_L__FUNCSIG__: IT = PredefinedExpr::LFuncSig; break; // [MS]
- case tok::kw___PRETTY_FUNCTION__: IT = PredefinedExpr::PrettyFunction; break;
+ case tok::kw___func__: IK = PredefinedExpr::Func; break; // [C99 6.4.2.2]
+ case tok::kw___FUNCTION__: IK = PredefinedExpr::Function; break;
+ case tok::kw___FUNCDNAME__: IK = PredefinedExpr::FuncDName; break; // [MS]
+ case tok::kw___FUNCSIG__: IK = PredefinedExpr::FuncSig; break; // [MS]
+ case tok::kw_L__FUNCTION__: IK = PredefinedExpr::LFunction; break; // [MS]
+ case tok::kw_L__FUNCSIG__: IK = PredefinedExpr::LFuncSig; break; // [MS]
+ case tok::kw___PRETTY_FUNCTION__: IK = PredefinedExpr::PrettyFunction; break;
}
- return BuildPredefinedExpr(Loc, IT);
+ return BuildPredefinedExpr(Loc, IK);
}
ExprResult Sema::ActOnCharacterConstant(const Token &Tok, Scope *UDLScope) {
@@ -3363,16 +3420,14 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) {
bool isSigned = !Literal.isUnsigned;
unsigned scale = Context.getFixedPointScale(Ty);
- unsigned ibits = Context.getFixedPointIBits(Ty);
unsigned bit_width = Context.getTypeInfo(Ty).Width;
llvm::APInt Val(bit_width, 0, isSigned);
bool Overflowed = Literal.GetFixedPointValue(Val, scale);
+ bool ValIsZero = Val.isNullValue() && !Overflowed;
- // Do not use bit_width since some types may have padding like _Fract or
- // unsigned _Accums if PaddingOnUnsignedFixedPoint is set.
- auto MaxVal = llvm::APInt::getMaxValue(ibits + scale).zextOrSelf(bit_width);
- if (Literal.isFract && Val == MaxVal + 1)
+ auto MaxVal = Context.getFixedPointMax(Ty).getValue();
+ if (Literal.isFract && Val == MaxVal + 1 && !ValIsZero)
// Clause 6.4.4 - The value of a constant shall be in the range of
// representable values for its type, with exception for constants of a
// fract type with a value of exactly 1; such a constant shall denote
@@ -3588,7 +3643,8 @@ static bool CheckExtensionTraitOperandType(Sema &S, QualType T,
// C99 6.5.3.4p1:
if (T->isFunctionType() &&
- (TraitKind == UETT_SizeOf || TraitKind == UETT_AlignOf)) {
+ (TraitKind == UETT_SizeOf || TraitKind == UETT_AlignOf ||
+ TraitKind == UETT_PreferredAlignOf)) {
// sizeof(function)/alignof(function) is allowed as an extension.
S.Diag(Loc, diag::ext_sizeof_alignof_function_type)
<< TraitKind << ArgRange;
@@ -3666,7 +3722,7 @@ bool Sema::CheckUnaryExprOrTypeTraitOperand(Expr *E,
// the expression to be complete. 'sizeof' requires the expression's type to
// be complete (and will attempt to complete it if it's an array of unknown
// bound).
- if (ExprKind == UETT_AlignOf) {
+ if (ExprKind == UETT_AlignOf || ExprKind == UETT_PreferredAlignOf) {
if (RequireCompleteType(E->getExprLoc(),
Context.getBaseElementType(E->getType()),
diag::err_sizeof_alignof_incomplete_type, ExprKind,
@@ -3690,7 +3746,8 @@ bool Sema::CheckUnaryExprOrTypeTraitOperand(Expr *E,
// The operand for sizeof and alignof is in an unevaluated expression context,
// so side effects could result in unintended consequences.
- if ((ExprKind == UETT_SizeOf || ExprKind == UETT_AlignOf) &&
+ if ((ExprKind == UETT_SizeOf || ExprKind == UETT_AlignOf ||
+ ExprKind == UETT_PreferredAlignOf) &&
!inTemplateInstantiation() && E->HasSideEffects(Context, false))
Diag(E->getExprLoc(), diag::warn_side_effects_unevaluated_context);
@@ -3759,7 +3816,8 @@ bool Sema::CheckUnaryExprOrTypeTraitOperand(QualType ExprType,
// C11 6.5.3.4/3, C++11 [expr.alignof]p3:
// When alignof or _Alignof is applied to an array type, the result
// is the alignment of the element type.
- if (ExprKind == UETT_AlignOf || ExprKind == UETT_OpenMPRequiredSimdAlign)
+ if (ExprKind == UETT_AlignOf || ExprKind == UETT_PreferredAlignOf ||
+ ExprKind == UETT_OpenMPRequiredSimdAlign)
ExprType = Context.getBaseElementType(ExprType);
if (ExprKind == UETT_VecStep)
@@ -3788,7 +3846,7 @@ bool Sema::CheckUnaryExprOrTypeTraitOperand(QualType ExprType,
return false;
}
-static bool CheckAlignOfExpr(Sema &S, Expr *E) {
+static bool CheckAlignOfExpr(Sema &S, Expr *E, UnaryExprOrTypeTrait ExprKind) {
E = E->IgnoreParens();
// Cannot know anything else if the expression is dependent.
@@ -3842,7 +3900,7 @@ static bool CheckAlignOfExpr(Sema &S, Expr *E) {
return false;
}
- return S.CheckUnaryExprOrTypeTraitOperand(E, UETT_AlignOf);
+ return S.CheckUnaryExprOrTypeTraitOperand(E, ExprKind);
}
bool Sema::CheckVecStepExpr(Expr *E) {
@@ -4038,8 +4096,8 @@ Sema::CreateUnaryExprOrTypeTraitExpr(Expr *E, SourceLocation OpLoc,
bool isInvalid = false;
if (E->isTypeDependent()) {
// Delay type-checking for type-dependent expressions.
- } else if (ExprKind == UETT_AlignOf) {
- isInvalid = CheckAlignOfExpr(*this, E);
+ } else if (ExprKind == UETT_AlignOf || ExprKind == UETT_PreferredAlignOf) {
+ isInvalid = CheckAlignOfExpr(*this, E, ExprKind);
} else if (ExprKind == UETT_VecStep) {
isInvalid = CheckVecStepExpr(E);
} else if (ExprKind == UETT_OpenMPRequiredSimdAlign) {
@@ -4238,7 +4296,57 @@ Sema::ActOnArraySubscriptExpr(Scope *S, Expr *base, SourceLocation lbLoc,
return CreateOverloadedArraySubscriptExpr(lbLoc, rbLoc, base, idx);
}
- return CreateBuiltinArraySubscriptExpr(base, lbLoc, idx, rbLoc);
+ ExprResult Res = CreateBuiltinArraySubscriptExpr(base, lbLoc, idx, rbLoc);
+
+ if (!Res.isInvalid() && isa<ArraySubscriptExpr>(Res.get()))
+ CheckSubscriptAccessOfNoDeref(cast<ArraySubscriptExpr>(Res.get()));
+
+ return Res;
+}
+
+void Sema::CheckAddressOfNoDeref(const Expr *E) {
+ ExpressionEvaluationContextRecord &LastRecord = ExprEvalContexts.back();
+ const Expr *StrippedExpr = E->IgnoreParenImpCasts();
+
+ // For expressions like `&(*s).b`, the base is recorded and what should be
+ // checked.
+ const MemberExpr *Member = nullptr;
+ while ((Member = dyn_cast<MemberExpr>(StrippedExpr)) && !Member->isArrow())
+ StrippedExpr = Member->getBase()->IgnoreParenImpCasts();
+
+ LastRecord.PossibleDerefs.erase(StrippedExpr);
+}
+
+void Sema::CheckSubscriptAccessOfNoDeref(const ArraySubscriptExpr *E) {
+ QualType ResultTy = E->getType();
+ ExpressionEvaluationContextRecord &LastRecord = ExprEvalContexts.back();
+
+ // Bail if the element is an array since it is not memory access.
+ if (isa<ArrayType>(ResultTy))
+ return;
+
+ if (ResultTy->hasAttr(attr::NoDeref)) {
+ LastRecord.PossibleDerefs.insert(E);
+ return;
+ }
+
+ // Check if the base type is a pointer to a member access of a struct
+ // marked with noderef.
+ const Expr *Base = E->getBase();
+ QualType BaseTy = Base->getType();
+ if (!(isa<ArrayType>(BaseTy) || isa<PointerType>(BaseTy)))
+ // Not a pointer access
+ return;
+
+ const MemberExpr *Member = nullptr;
+ while ((Member = dyn_cast<MemberExpr>(Base->IgnoreParenCasts())) &&
+ Member->isArrow())
+ Base = Member->getBase();
+
+ if (const auto *Ptr = dyn_cast<PointerType>(Base->getType())) {
+ if (Ptr->getPointeeType()->hasAttr(attr::NoDeref))
+ LastRecord.PossibleDerefs.insert(E);
+ }
}
ExprResult Sema::ActOnOMPArraySectionExpr(Expr *Base, SourceLocation LBLoc,
@@ -4339,10 +4447,11 @@ ExprResult Sema::ActOnOMPArraySectionExpr(Expr *Base, SourceLocation LBLoc,
return ExprError();
if (LowerBound && !OriginalTy->isAnyPointerType()) {
- llvm::APSInt LowerBoundValue;
- if (LowerBound->EvaluateAsInt(LowerBoundValue, Context)) {
+ Expr::EvalResult Result;
+ if (LowerBound->EvaluateAsInt(Result, Context)) {
// OpenMP 4.5, [2.4 Array Sections]
// The array section must be a subset of the original array.
+ llvm::APSInt LowerBoundValue = Result.Val.getInt();
if (LowerBoundValue.isNegative()) {
Diag(LowerBound->getExprLoc(), diag::err_omp_section_not_subset_of_array)
<< LowerBound->getSourceRange();
@@ -4352,10 +4461,11 @@ ExprResult Sema::ActOnOMPArraySectionExpr(Expr *Base, SourceLocation LBLoc,
}
if (Length) {
- llvm::APSInt LengthValue;
- if (Length->EvaluateAsInt(LengthValue, Context)) {
+ Expr::EvalResult Result;
+ if (Length->EvaluateAsInt(Result, Context)) {
// OpenMP 4.5, [2.4 Array Sections]
// The length must evaluate to non-negative integers.
+ llvm::APSInt LengthValue = Result.Val.getInt();
if (LengthValue.isNegative()) {
Diag(Length->getExprLoc(), diag::err_omp_section_length_negative)
<< LengthValue.toString(/*Radix=*/10, /*Signed=*/true)
@@ -4488,8 +4598,8 @@ Sema::CreateBuiltinArraySubscriptExpr(Expr *Base, SourceLocation LLoc,
// wasn't promoted because of the C90 rule that doesn't
// allow promoting non-lvalue arrays. Warn, then
// force the promotion here.
- Diag(LHSExp->getLocStart(), diag::ext_subscript_non_lvalue) <<
- LHSExp->getSourceRange();
+ Diag(LHSExp->getBeginLoc(), diag::ext_subscript_non_lvalue)
+ << LHSExp->getSourceRange();
LHSExp = ImpCastExprToType(LHSExp, Context.getArrayDecayedType(LHSTy),
CK_ArrayToPointerDecay).get();
LHSTy = LHSExp->getType();
@@ -4499,8 +4609,8 @@ Sema::CreateBuiltinArraySubscriptExpr(Expr *Base, SourceLocation LLoc,
ResultType = LHSTy->getAs<PointerType>()->getPointeeType();
} else if (RHSTy->isArrayType()) {
// Same as previous, except for 123[f().a] case
- Diag(RHSExp->getLocStart(), diag::ext_subscript_non_lvalue) <<
- RHSExp->getSourceRange();
+ Diag(RHSExp->getBeginLoc(), diag::ext_subscript_non_lvalue)
+ << RHSExp->getSourceRange();
RHSExp = ImpCastExprToType(RHSExp, Context.getArrayDecayedType(RHSTy),
CK_ArrayToPointerDecay).get();
RHSTy = RHSExp->getType();
@@ -4527,8 +4637,8 @@ Sema::CreateBuiltinArraySubscriptExpr(Expr *Base, SourceLocation LLoc,
// type. Note that Functions are not objects, and that (in C99 parlance)
// incomplete types are not object types.
if (ResultType->isFunctionType()) {
- Diag(BaseExpr->getLocStart(), diag::err_subscript_function_type)
- << ResultType << BaseExpr->getSourceRange();
+ Diag(BaseExpr->getBeginLoc(), diag::err_subscript_function_type)
+ << ResultType << BaseExpr->getSourceRange();
return ExprError();
}
@@ -4594,7 +4704,7 @@ bool Sema::CheckCXXDefaultArgExpr(SourceLocation CallLoc, FunctionDecl *FD,
if (Inst.isInvalid())
return true;
if (Inst.isAlreadyInstantiating()) {
- Diag(Param->getLocStart(), diag::err_recursive_default_argument) << FD;
+ Diag(Param->getBeginLoc(), diag::err_recursive_default_argument) << FD;
Param->setInvalidDecl();
return true;
}
@@ -4616,9 +4726,9 @@ bool Sema::CheckCXXDefaultArgExpr(SourceLocation CallLoc, FunctionDecl *FD,
// Check the expression as an initializer for the parameter.
InitializedEntity Entity
= InitializedEntity::InitializeParameter(Context, Param);
- InitializationKind Kind
- = InitializationKind::CreateCopy(Param->getLocation(),
- /*FIXME:EqualLoc*/UninstExpr->getLocStart());
+ InitializationKind Kind = InitializationKind::CreateCopy(
+ Param->getLocation(),
+ /*FIXME:EqualLoc*/ UninstExpr->getBeginLoc());
Expr *ResultE = Result.getAs<Expr>();
InitializationSequence InitSeq(*this, Entity, Kind, ResultE);
@@ -4626,8 +4736,9 @@ bool Sema::CheckCXXDefaultArgExpr(SourceLocation CallLoc, FunctionDecl *FD,
if (Result.isInvalid())
return true;
- Result = ActOnFinishFullExpr(Result.getAs<Expr>(),
- Param->getOuterLocStart());
+ Result =
+ ActOnFinishFullExpr(Result.getAs<Expr>(), Param->getOuterLocStart(),
+ /*DiscardedValue*/ false);
if (Result.isInvalid())
return true;
@@ -4640,7 +4751,7 @@ bool Sema::CheckCXXDefaultArgExpr(SourceLocation CallLoc, FunctionDecl *FD,
// If the default argument expression is not set yet, we are building it now.
if (!Param->hasInit()) {
- Diag(Param->getLocStart(), diag::err_recursive_default_argument) << FD;
+ Diag(Param->getBeginLoc(), diag::err_recursive_default_argument) << FD;
Param->setInvalidDecl();
return true;
}
@@ -4725,7 +4836,7 @@ static TypoCorrection TryTypoCorrectionForCall(Sema &S, Expr *Fn,
ArrayRef<Expr *> Args) {
MemberExpr *ME = dyn_cast<MemberExpr>(Fn);
DeclarationName FuncName = FDecl->getDeclName();
- SourceLocation NameLoc = ME ? ME->getMemberLoc() : Fn->getLocStart();
+ SourceLocation NameLoc = ME ? ME->getMemberLoc() : Fn->getBeginLoc();
if (TypoCorrection Corrected = S.CorrectTypo(
DeclarationNameInfo(FuncName, NameLoc), Sema::LookupOrdinaryName,
@@ -4816,12 +4927,14 @@ Sema::ConvertArgumentsForCall(CallExpr *Call, Expr *Fn,
// Emit the location of the prototype.
if (!TC && FDecl && !FDecl->getBuiltinID() && !IsExecConfig)
- Diag(FDecl->getLocStart(), diag::note_callee_decl)
- << FDecl;
+ Diag(FDecl->getBeginLoc(), diag::note_callee_decl) << FDecl;
return true;
}
- Call->setNumArgs(Context, NumParams);
+ // We reserve space for the default arguments when we create
+ // the call expression, before calling ConvertArgumentsForCall.
+ assert((Call->getNumArgs() == NumParams) &&
+ "We should have reserved space for the default arguments before!");
}
// If too many are passed and not variadic, error on the extras and drop
@@ -4839,39 +4952,38 @@ Sema::ConvertArgumentsForCall(CallExpr *Call, Expr *Fn,
<< TC.getCorrectionRange());
} else if (NumParams == 1 && FDecl &&
FDecl->getParamDecl(0)->getDeclName())
- Diag(Args[NumParams]->getLocStart(),
+ Diag(Args[NumParams]->getBeginLoc(),
MinArgs == NumParams
? diag::err_typecheck_call_too_many_args_one
: diag::err_typecheck_call_too_many_args_at_most_one)
<< FnKind << FDecl->getParamDecl(0)
<< static_cast<unsigned>(Args.size()) << Fn->getSourceRange()
- << SourceRange(Args[NumParams]->getLocStart(),
- Args.back()->getLocEnd());
+ << SourceRange(Args[NumParams]->getBeginLoc(),
+ Args.back()->getEndLoc());
else
- Diag(Args[NumParams]->getLocStart(),
+ Diag(Args[NumParams]->getBeginLoc(),
MinArgs == NumParams
? diag::err_typecheck_call_too_many_args
: diag::err_typecheck_call_too_many_args_at_most)
<< FnKind << NumParams << static_cast<unsigned>(Args.size())
<< Fn->getSourceRange()
- << SourceRange(Args[NumParams]->getLocStart(),
- Args.back()->getLocEnd());
+ << SourceRange(Args[NumParams]->getBeginLoc(),
+ Args.back()->getEndLoc());
// Emit the location of the prototype.
if (!TC && FDecl && !FDecl->getBuiltinID() && !IsExecConfig)
- Diag(FDecl->getLocStart(), diag::note_callee_decl)
- << FDecl;
+ Diag(FDecl->getBeginLoc(), diag::note_callee_decl) << FDecl;
// This deletes the extra arguments.
- Call->setNumArgs(Context, NumParams);
+ Call->shrinkNumArgs(NumParams);
return true;
}
}
SmallVector<Expr *, 8> AllArgs;
VariadicCallType CallType = getVariadicCallType(FDecl, Proto, Fn);
- Invalid = GatherArgumentsForCall(Call->getLocStart(), FDecl,
- Proto, 0, Args, AllArgs, CallType);
+ Invalid = GatherArgumentsForCall(Call->getBeginLoc(), FDecl, Proto, 0, Args,
+ AllArgs, CallType);
if (Invalid)
return true;
unsigned TotalNumArgs = AllArgs.size();
@@ -4899,8 +5011,7 @@ bool Sema::GatherArgumentsForCall(SourceLocation CallLoc, FunctionDecl *FDecl,
if (ArgIx < Args.size()) {
Arg = Args[ArgIx++];
- if (RequireCompleteType(Arg->getLocStart(),
- ProtoArgType,
+ if (RequireCompleteType(Arg->getBeginLoc(), ProtoArgType,
diag::err_call_incomplete_argument, Arg))
return true;
@@ -5058,6 +5169,9 @@ static bool isPlaceholderToRemoveAsArg(QualType type) {
#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
case BuiltinType::Id:
#include "clang/Basic/OpenCLImageTypes.def"
+#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
+ case BuiltinType::Id:
+#include "clang/Basic/OpenCLExtensionTypes.def"
#define PLACEHOLDER_TYPE(ID, SINGLETON_ID)
#define BUILTIN_TYPE(ID, SINGLETON_ID) case BuiltinType::ID:
#include "clang/AST/BuiltinTypes.def"
@@ -5153,10 +5267,13 @@ static FunctionDecl *rewriteBuiltinFunctionDecl(Sema *Sema, ASTContext &Context,
continue;
}
+ QualType PointeeType = ParamType->getPointeeType();
+ if (PointeeType.getQualifiers().hasAddressSpace())
+ continue;
+
NeedsNewDecl = true;
LangAS AS = ArgType->getPointeeType().getAddressSpace();
- QualType PointeeType = ParamType->getPointeeType();
PointeeType = Context.getAddrSpaceQualType(PointeeType, AS);
OverloadParams.push_back(Context.getPointerType(PointeeType));
}
@@ -5205,7 +5322,7 @@ static void checkDirectCallValidity(Sema &S, const Expr *Fn,
return;
if (const EnableIfAttr *Attr = S.CheckEnableIf(Callee, ArgExprs, true)) {
- S.Diag(Fn->getLocStart(),
+ S.Diag(Fn->getBeginLoc(),
isa<CXXMethodDecl>(Callee)
? diag::err_ovl_no_viable_member_function_in_call
: diag::err_ovl_no_viable_function_in_call)
@@ -5317,14 +5434,14 @@ ExprResult Sema::ActOnCallExpr(Scope *Scope, Expr *Fn, SourceLocation LParenLoc,
if (isa<CXXPseudoDestructorExpr>(Fn)) {
if (!ArgExprs.empty()) {
// Pseudo-destructor calls should not have any arguments.
- Diag(Fn->getLocStart(), diag::err_pseudo_dtor_call_with_args)
+ Diag(Fn->getBeginLoc(), diag::err_pseudo_dtor_call_with_args)
<< FixItHint::CreateRemoval(
- SourceRange(ArgExprs.front()->getLocStart(),
- ArgExprs.back()->getLocEnd()));
+ SourceRange(ArgExprs.front()->getBeginLoc(),
+ ArgExprs.back()->getEndLoc()));
}
- return new (Context)
- CallExpr(Context, Fn, None, Context.VoidTy, VK_RValue, RParenLoc);
+ return CallExpr::Create(Context, Fn, /*Args=*/{}, Context.VoidTy,
+ VK_RValue, RParenLoc);
}
if (Fn->getType() == Context.PseudoObjectTy) {
ExprResult result = CheckPlaceholderExpr(Fn);
@@ -5334,25 +5451,19 @@ ExprResult Sema::ActOnCallExpr(Scope *Scope, Expr *Fn, SourceLocation LParenLoc,
// Determine whether this is a dependent call inside a C++ template,
// in which case we won't do any semantic analysis now.
- bool Dependent = false;
- if (Fn->isTypeDependent())
- Dependent = true;
- else if (Expr::hasAnyTypeDependentArguments(ArgExprs))
- Dependent = true;
-
- if (Dependent) {
+ if (Fn->isTypeDependent() || Expr::hasAnyTypeDependentArguments(ArgExprs)) {
if (ExecConfig) {
- return new (Context) CUDAKernelCallExpr(
+ return CUDAKernelCallExpr::Create(
Context, Fn, cast<CallExpr>(ExecConfig), ArgExprs,
Context.DependentTy, VK_RValue, RParenLoc);
} else {
- tryImplicitlyCaptureThisIfImplicitMemberFunctionAccessWithDependentArgs(
+ tryImplicitlyCaptureThisIfImplicitMemberFunctionAccessWithDependentArgs(
*this, dyn_cast<UnresolvedMemberExpr>(Fn->IgnoreParens()),
- Fn->getLocStart());
+ Fn->getBeginLoc());
- return new (Context) CallExpr(
- Context, Fn, ArgExprs, Context.DependentTy, VK_RValue, RParenLoc);
+ return CallExpr::Create(Context, Fn, ArgExprs, Context.DependentTy,
+ VK_RValue, RParenLoc);
}
}
@@ -5380,8 +5491,8 @@ ExprResult Sema::ActOnCallExpr(Scope *Scope, Expr *Fn, SourceLocation LParenLoc,
// We aren't supposed to apply this logic if there's an '&' involved.
if (!find.HasFormOfMemberPointer) {
if (Expr::hasAnyTypeDependentArguments(ArgExprs))
- return new (Context) CallExpr(
- Context, Fn, ArgExprs, Context.DependentTy, VK_RValue, RParenLoc);
+ return CallExpr::Create(Context, Fn, ArgExprs, Context.DependentTy,
+ VK_RValue, RParenLoc);
OverloadExpr *ovl = find.Expression;
if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(ovl))
return BuildOverloadedCallExpr(
@@ -5430,9 +5541,8 @@ ExprResult Sema::ActOnCallExpr(Scope *Scope, Expr *Fn, SourceLocation LParenLoc,
NDecl = cast<MemberExpr>(NakedFn)->getMemberDecl();
if (FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(NDecl)) {
- if (CallingNDeclIndirectly &&
- !checkAddressOfFunctionIsAvailable(FD, /*Complain=*/true,
- Fn->getLocStart()))
+ if (CallingNDeclIndirectly && !checkAddressOfFunctionIsAvailable(
+ FD, /*Complain=*/true, Fn->getBeginLoc()))
return ExprError();
if (getLangOpts().OpenCL && checkOpenCLDisabledDecl(*FD, *Fn))
@@ -5484,12 +5594,11 @@ ExprResult Sema::ActOnConvertVectorExpr(Expr *E, ParsedType ParsedDestTy,
/// block-pointer type.
///
/// \param NDecl the declaration being called, if available
-ExprResult
-Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl,
- SourceLocation LParenLoc,
- ArrayRef<Expr *> Args,
- SourceLocation RParenLoc,
- Expr *Config, bool IsExecConfig) {
+ExprResult Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl,
+ SourceLocation LParenLoc,
+ ArrayRef<Expr *> Args,
+ SourceLocation RParenLoc, Expr *Config,
+ bool IsExecConfig, ADLCallKind UsesADL) {
FunctionDecl *FDecl = dyn_cast_or_null<FunctionDecl>(NDecl);
unsigned BuiltinID = (FDecl ? FDecl->getBuiltinID() : 0);
@@ -5514,28 +5623,71 @@ Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl,
// We special-case function promotion here because we only allow promoting
// builtin functions to function pointers in the callee of a call.
ExprResult Result;
+ QualType ResultTy;
if (BuiltinID &&
Fn->getType()->isSpecificBuiltinType(BuiltinType::BuiltinFn)) {
- Result = ImpCastExprToType(Fn, Context.getPointerType(FDecl->getType()),
- CK_BuiltinFnToFnPtr).get();
+ // Extract the return type from the (builtin) function pointer type.
+ // FIXME Several builtins still have setType in
+ // Sema::CheckBuiltinFunctionCall. One should review their definitions in
+ // Builtins.def to ensure they are correct before removing setType calls.
+ QualType FnPtrTy = Context.getPointerType(FDecl->getType());
+ Result = ImpCastExprToType(Fn, FnPtrTy, CK_BuiltinFnToFnPtr).get();
+ ResultTy = FDecl->getCallResultType();
} else {
Result = CallExprUnaryConversions(Fn);
+ ResultTy = Context.BoolTy;
}
if (Result.isInvalid())
return ExprError();
Fn = Result.get();
- // Make the call expr early, before semantic checks. This guarantees cleanup
- // of arguments and function on error.
+ // Check for a valid function type, but only if it is not a builtin which
+ // requires custom type checking. These will be handled by
+ // CheckBuiltinFunctionCall below just after creation of the call expression.
+ const FunctionType *FuncT = nullptr;
+ if (!BuiltinID || !Context.BuiltinInfo.hasCustomTypechecking(BuiltinID)) {
+ retry:
+ if (const PointerType *PT = Fn->getType()->getAs<PointerType>()) {
+ // C99 6.5.2.2p1 - "The expression that denotes the called function shall
+ // have type pointer to function".
+ FuncT = PT->getPointeeType()->getAs<FunctionType>();
+ if (!FuncT)
+ return ExprError(Diag(LParenLoc, diag::err_typecheck_call_not_function)
+ << Fn->getType() << Fn->getSourceRange());
+ } else if (const BlockPointerType *BPT =
+ Fn->getType()->getAs<BlockPointerType>()) {
+ FuncT = BPT->getPointeeType()->castAs<FunctionType>();
+ } else {
+ // Handle calls to expressions of unknown-any type.
+ if (Fn->getType() == Context.UnknownAnyTy) {
+ ExprResult rewrite = rebuildUnknownAnyFunction(*this, Fn);
+ if (rewrite.isInvalid()) return ExprError();
+ Fn = rewrite.get();
+ goto retry;
+ }
+
+ return ExprError(Diag(LParenLoc, diag::err_typecheck_call_not_function)
+ << Fn->getType() << Fn->getSourceRange());
+ }
+ }
+
+ // Get the number of parameters in the function prototype, if any.
+ // We will allocate space for max(Args.size(), NumParams) arguments
+ // in the call expression.
+ const auto *Proto = dyn_cast_or_null<FunctionProtoType>(FuncT);
+ unsigned NumParams = Proto ? Proto->getNumParams() : 0;
+
CallExpr *TheCall;
- if (Config)
- TheCall = new (Context) CUDAKernelCallExpr(Context, Fn,
- cast<CallExpr>(Config), Args,
- Context.BoolTy, VK_RValue,
- RParenLoc);
- else
- TheCall = new (Context) CallExpr(Context, Fn, Args, Context.BoolTy,
- VK_RValue, RParenLoc);
+ if (Config) {
+ assert(UsesADL == ADLCallKind::NotADL &&
+ "CUDAKernelCallExpr should not use ADL");
+ TheCall =
+ CUDAKernelCallExpr::Create(Context, Fn, cast<CallExpr>(Config), Args,
+ ResultTy, VK_RValue, RParenLoc, NumParams);
+ } else {
+ TheCall = CallExpr::Create(Context, Fn, Args, ResultTy, VK_RValue,
+ RParenLoc, NumParams, UsesADL);
+ }
if (!getLangOpts().CPlusPlus) {
// C cannot always handle TypoExpr nodes in builtin calls and direct
@@ -5546,39 +5698,16 @@ Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl,
if (!Result.isUsable()) return ExprError();
TheCall = dyn_cast<CallExpr>(Result.get());
if (!TheCall) return Result;
- Args = llvm::makeArrayRef(TheCall->getArgs(), TheCall->getNumArgs());
+ // TheCall at this point has max(Args.size(), NumParams) arguments,
+ // with extra arguments nulled. We don't want to introduce nulled
+ // arguments in Args and so we only take the first Args.size() arguments.
+ Args = llvm::makeArrayRef(TheCall->getArgs(), Args.size());
}
- // Bail out early if calling a builtin with custom typechecking.
+ // Bail out early if calling a builtin with custom type checking.
if (BuiltinID && Context.BuiltinInfo.hasCustomTypechecking(BuiltinID))
return CheckBuiltinFunctionCall(FDecl, BuiltinID, TheCall);
- retry:
- const FunctionType *FuncT;
- if (const PointerType *PT = Fn->getType()->getAs<PointerType>()) {
- // C99 6.5.2.2p1 - "The expression that denotes the called function shall
- // have type pointer to function".
- FuncT = PT->getPointeeType()->getAs<FunctionType>();
- if (!FuncT)
- return ExprError(Diag(LParenLoc, diag::err_typecheck_call_not_function)
- << Fn->getType() << Fn->getSourceRange());
- } else if (const BlockPointerType *BPT =
- Fn->getType()->getAs<BlockPointerType>()) {
- FuncT = BPT->getPointeeType()->castAs<FunctionType>();
- } else {
- // Handle calls to expressions of unknown-any type.
- if (Fn->getType() == Context.UnknownAnyTy) {
- ExprResult rewrite = rebuildUnknownAnyFunction(*this, Fn);
- if (rewrite.isInvalid()) return ExprError();
- Fn = rewrite.get();
- TheCall->setCallee(Fn);
- goto retry;
- }
-
- return ExprError(Diag(LParenLoc, diag::err_typecheck_call_not_function)
- << Fn->getType() << Fn->getSourceRange());
- }
-
if (getLangOpts().CUDA) {
if (Config) {
// CUDA: Kernel calls must be to global functions
@@ -5599,7 +5728,7 @@ Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl,
}
// Check for a valid return type
- if (CheckCallReturnType(FuncT->getReturnType(), Fn->getLocStart(), TheCall,
+ if (CheckCallReturnType(FuncT->getReturnType(), Fn->getBeginLoc(), TheCall,
FDecl))
return ExprError();
@@ -5607,7 +5736,6 @@ Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl,
TheCall->setType(FuncT->getCallResultType(Context));
TheCall->setValueKind(Expr::getValueKindForType(FuncT->getReturnType()));
- const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(FuncT);
if (Proto) {
if (ConvertArgumentsForCall(TheCall, Fn, FDecl, Proto, Args, RParenLoc,
IsExecConfig))
@@ -5655,8 +5783,7 @@ Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl,
Arg = ArgE.getAs<Expr>();
}
- if (RequireCompleteType(Arg->getLocStart(),
- Arg->getType(),
+ if (RequireCompleteType(Arg->getBeginLoc(), Arg->getType(),
diag::err_call_incomplete_argument, Arg))
return ExprError();
@@ -5739,13 +5866,6 @@ Sema::BuildCompoundLiteralExpr(SourceLocation LParenLoc, TypeSourceInfo *TInfo,
LiteralExpr = Result.get();
bool isFileScope = !CurContext->isFunctionOrMethod();
- if (isFileScope &&
- !LiteralExpr->isTypeDependent() &&
- !LiteralExpr->isValueDependent() &&
- !literalType->isDependentType()) { // 6.5.2.5p3
- if (CheckForConstantInitializer(LiteralExpr, literalType))
- return ExprError();
- }
// In C, compound literals are l-values for some reason.
// For GCC compatibility, in C++, file-scope array compound literals with
@@ -5770,9 +5890,32 @@ Sema::BuildCompoundLiteralExpr(SourceLocation LParenLoc, TypeSourceInfo *TInfo,
? VK_RValue
: VK_LValue;
- return MaybeBindToTemporary(
- new (Context) CompoundLiteralExpr(LParenLoc, TInfo, literalType,
- VK, LiteralExpr, isFileScope));
+ if (isFileScope)
+ if (auto ILE = dyn_cast<InitListExpr>(LiteralExpr))
+ for (unsigned i = 0, j = ILE->getNumInits(); i != j; i++) {
+ Expr *Init = ILE->getInit(i);
+ ILE->setInit(i, ConstantExpr::Create(Context, Init));
+ }
+
+ Expr *E = new (Context) CompoundLiteralExpr(LParenLoc, TInfo, literalType,
+ VK, LiteralExpr, isFileScope);
+ if (isFileScope) {
+ if (!LiteralExpr->isTypeDependent() &&
+ !LiteralExpr->isValueDependent() &&
+ !literalType->isDependentType()) // C99 6.5.2.5p3
+ if (CheckForConstantInitializer(LiteralExpr, literalType))
+ return ExprError();
+ } else if (literalType.getAddressSpace() != LangAS::opencl_private &&
+ literalType.getAddressSpace() != LangAS::Default) {
+ // Embedded-C extensions to C99 6.5.2.5:
+ // "If the compound literal occurs inside the body of a function, the
+ // type name shall not be qualified by an address-space qualifier."
+ Diag(LParenLoc, diag::err_compound_literal_with_address_space)
+ << SourceRange(LParenLoc, LiteralExpr->getSourceRange().getEnd());
+ return ExprError();
+ }
+
+ return MaybeBindToTemporary(E);
}
ExprResult
@@ -5854,6 +5997,8 @@ CastKind Sema::PrepareScalarCast(ExprResult &Src, QualType DestTy) {
LangAS DestAS = DestTy->getPointeeType().getAddressSpace();
if (SrcAS != DestAS)
return CK_AddressSpaceConversion;
+ if (Context.hasCvrSimilarType(SrcTy, DestTy))
+ return CK_NoOp;
return CK_BitCast;
}
case Type::STK_BlockPointer:
@@ -5874,10 +6019,33 @@ CastKind Sema::PrepareScalarCast(ExprResult &Src, QualType DestTy) {
case Type::STK_FloatingComplex:
case Type::STK_IntegralComplex:
case Type::STK_MemberPointer:
+ case Type::STK_FixedPoint:
llvm_unreachable("illegal cast from pointer");
}
llvm_unreachable("Should have returned before this");
+ case Type::STK_FixedPoint:
+ switch (DestTy->getScalarTypeKind()) {
+ case Type::STK_FixedPoint:
+ return CK_FixedPointCast;
+ case Type::STK_Bool:
+ return CK_FixedPointToBoolean;
+ case Type::STK_Integral:
+ case Type::STK_Floating:
+ case Type::STK_IntegralComplex:
+ case Type::STK_FloatingComplex:
+ Diag(Src.get()->getExprLoc(),
+ diag::err_unimplemented_conversion_with_fixed_point_type)
+ << DestTy;
+ return CK_IntegralCast;
+ case Type::STK_CPointer:
+ case Type::STK_ObjCObjectPointer:
+ case Type::STK_BlockPointer:
+ case Type::STK_MemberPointer:
+ llvm_unreachable("illegal cast to pointer type");
+ }
+ llvm_unreachable("Should have returned before this");
+
case Type::STK_Bool: // casting from bool is like casting from an integer
case Type::STK_Integral:
switch (DestTy->getScalarTypeKind()) {
@@ -5906,6 +6074,11 @@ CastKind Sema::PrepareScalarCast(ExprResult &Src, QualType DestTy) {
return CK_FloatingRealToComplex;
case Type::STK_MemberPointer:
llvm_unreachable("member pointer type in C");
+ case Type::STK_FixedPoint:
+ Diag(Src.get()->getExprLoc(),
+ diag::err_unimplemented_conversion_with_fixed_point_type)
+ << SrcTy;
+ return CK_IntegralCast;
}
llvm_unreachable("Should have returned before this");
@@ -5933,6 +6106,11 @@ CastKind Sema::PrepareScalarCast(ExprResult &Src, QualType DestTy) {
llvm_unreachable("valid float->pointer cast?");
case Type::STK_MemberPointer:
llvm_unreachable("member pointer type in C");
+ case Type::STK_FixedPoint:
+ Diag(Src.get()->getExprLoc(),
+ diag::err_unimplemented_conversion_with_fixed_point_type)
+ << SrcTy;
+ return CK_IntegralCast;
}
llvm_unreachable("Should have returned before this");
@@ -5962,6 +6140,11 @@ CastKind Sema::PrepareScalarCast(ExprResult &Src, QualType DestTy) {
llvm_unreachable("valid complex float->pointer cast?");
case Type::STK_MemberPointer:
llvm_unreachable("member pointer type in C");
+ case Type::STK_FixedPoint:
+ Diag(Src.get()->getExprLoc(),
+ diag::err_unimplemented_conversion_with_fixed_point_type)
+ << SrcTy;
+ return CK_IntegralCast;
}
llvm_unreachable("Should have returned before this");
@@ -5991,6 +6174,11 @@ CastKind Sema::PrepareScalarCast(ExprResult &Src, QualType DestTy) {
llvm_unreachable("valid complex int->pointer cast?");
case Type::STK_MemberPointer:
llvm_unreachable("member pointer type in C");
+ case Type::STK_FixedPoint:
+ Diag(Src.get()->getExprLoc(),
+ diag::err_unimplemented_conversion_with_fixed_point_type)
+ << SrcTy;
+ return CK_IntegralCast;
}
llvm_unreachable("Should have returned before this");
}
@@ -6323,8 +6511,7 @@ Sema::MaybeConvertParenListExprToParenExpr(Scope *S, Expr *OrigExpr) {
ExprResult Sema::ActOnParenListExpr(SourceLocation L,
SourceLocation R,
MultiExprArg Val) {
- Expr *expr = new (Context) ParenListExpr(Context, L, Val, R);
- return expr;
+ return ParenListExpr::Create(Context, L, Val, R);
}
/// Emit a specialized diagnostic when one expression is a null pointer
@@ -6394,11 +6581,11 @@ static QualType checkConditionalVoidType(Sema &S, ExprResult &LHS,
Expr *RHSExpr = RHS.get();
if (!LHSExpr->getType()->isVoidType())
- S.Diag(RHSExpr->getLocStart(), diag::ext_typecheck_cond_one_void)
- << RHSExpr->getSourceRange();
+ S.Diag(RHSExpr->getBeginLoc(), diag::ext_typecheck_cond_one_void)
+ << RHSExpr->getSourceRange();
if (!RHSExpr->getType()->isVoidType())
- S.Diag(LHSExpr->getLocStart(), diag::ext_typecheck_cond_one_void)
- << LHSExpr->getSourceRange();
+ S.Diag(LHSExpr->getBeginLoc(), diag::ext_typecheck_cond_one_void)
+ << LHSExpr->getSourceRange();
LHS = S.ImpCastExprToType(LHS.get(), S.Context.VoidTy, CK_ToVoid);
RHS = S.ImpCastExprToType(RHS.get(), S.Context.VoidTy, CK_ToVoid);
return S.Context.VoidTy;
@@ -6458,20 +6645,18 @@ static QualType checkConditionalPointerCompatibility(Sema &S, ExprResult &LHS,
LangAS ResultAddrSpace = LangAS::Default;
LangAS LAddrSpace = lhQual.getAddressSpace();
LangAS RAddrSpace = rhQual.getAddressSpace();
- if (S.getLangOpts().OpenCL) {
- // OpenCL v1.1 s6.5 - Conversion between pointers to distinct address
- // spaces is disallowed.
- if (lhQual.isAddressSpaceSupersetOf(rhQual))
- ResultAddrSpace = LAddrSpace;
- else if (rhQual.isAddressSpaceSupersetOf(lhQual))
- ResultAddrSpace = RAddrSpace;
- else {
- S.Diag(Loc,
- diag::err_typecheck_op_on_nonoverlapping_address_space_pointers)
- << LHSTy << RHSTy << 2 << LHS.get()->getSourceRange()
- << RHS.get()->getSourceRange();
- return QualType();
- }
+
+ // OpenCL v1.1 s6.5 - Conversion between pointers to distinct address
+ // spaces is disallowed.
+ if (lhQual.isAddressSpaceSupersetOf(rhQual))
+ ResultAddrSpace = LAddrSpace;
+ else if (rhQual.isAddressSpaceSupersetOf(lhQual))
+ ResultAddrSpace = RAddrSpace;
+ else {
+ S.Diag(Loc, diag::err_typecheck_op_on_nonoverlapping_address_space_pointers)
+ << LHSTy << RHSTy << 2 << LHS.get()->getSourceRange()
+ << RHS.get()->getSourceRange();
+ return QualType();
}
unsigned MergedCVRQual = lhQual.getCVRQualifiers() | rhQual.getCVRQualifiers();
@@ -6489,16 +6674,12 @@ static QualType checkConditionalPointerCompatibility(Sema &S, ExprResult &LHS,
// Thus for conditional operator we merge CVR and address space unqualified
// pointees and if there is a composite type we return a pointer to it with
// merged qualifiers.
- if (S.getLangOpts().OpenCL) {
- LHSCastKind = LAddrSpace == ResultAddrSpace
- ? CK_BitCast
- : CK_AddressSpaceConversion;
- RHSCastKind = RAddrSpace == ResultAddrSpace
- ? CK_BitCast
- : CK_AddressSpaceConversion;
- lhQual.removeAddressSpace();
- rhQual.removeAddressSpace();
- }
+ LHSCastKind =
+ LAddrSpace == ResultAddrSpace ? CK_BitCast : CK_AddressSpaceConversion;
+ RHSCastKind =
+ RAddrSpace == ResultAddrSpace ? CK_BitCast : CK_AddressSpaceConversion;
+ lhQual.removeAddressSpace();
+ rhQual.removeAddressSpace();
lhptee = S.Context.getQualifiedType(lhptee.getUnqualifiedType(), lhQual);
rhptee = S.Context.getQualifiedType(rhptee.getUnqualifiedType(), rhQual);
@@ -6514,6 +6695,7 @@ static QualType checkConditionalPointerCompatibility(Sema &S, ExprResult &LHS,
S.Context.getAddrSpaceQualType(S.Context.VoidTy, ResultAddrSpace));
LHS = S.ImpCastExprToType(LHS.get(), incompatTy, LHSCastKind);
RHS = S.ImpCastExprToType(RHS.get(), incompatTy, RHSCastKind);
+
// FIXME: For OpenCL the warning emission and cast to void* leaves a room
// for casts between types with incompatible address space qualifiers.
// For the following code the compiler produces casts between global and
@@ -6524,6 +6706,7 @@ static QualType checkConditionalPointerCompatibility(Sema &S, ExprResult &LHS,
S.Diag(Loc, diag::ext_typecheck_cond_incompatible_pointers)
<< LHSTy << RHSTy << LHS.get()->getSourceRange()
<< RHS.get()->getSourceRange();
+
return incompatTy;
}
@@ -7219,14 +7402,15 @@ static void DiagnoseConditionalPrecedence(Sema &Self,
<< Condition->getSourceRange()
<< BinaryOperator::getOpcodeStr(CondOpcode);
- SuggestParentheses(Self, OpLoc,
- Self.PDiag(diag::note_precedence_silence)
- << BinaryOperator::getOpcodeStr(CondOpcode),
- SourceRange(Condition->getLocStart(), Condition->getLocEnd()));
+ SuggestParentheses(
+ Self, OpLoc,
+ Self.PDiag(diag::note_precedence_silence)
+ << BinaryOperator::getOpcodeStr(CondOpcode),
+ SourceRange(Condition->getBeginLoc(), Condition->getEndLoc()));
SuggestParentheses(Self, OpLoc,
- Self.PDiag(diag::note_precedence_conditional_first),
- SourceRange(CondRHS->getLocStart(), RHSExpr->getLocEnd()));
+ Self.PDiag(diag::note_precedence_conditional_first),
+ SourceRange(CondRHS->getBeginLoc(), RHSExpr->getEndLoc()));
}
/// Compute the nullability of a conditional expression.
@@ -7757,7 +7941,12 @@ Sema::CheckAssignmentConstraints(QualType LHSType, ExprResult &RHS,
if (isa<PointerType>(RHSType)) {
LangAS AddrSpaceL = LHSPointer->getPointeeType().getAddressSpace();
LangAS AddrSpaceR = RHSType->getPointeeType().getAddressSpace();
- Kind = AddrSpaceL != AddrSpaceR ? CK_AddressSpaceConversion : CK_BitCast;
+ if (AddrSpaceL != AddrSpaceR)
+ Kind = CK_AddressSpaceConversion;
+ else if (Context.hasCvrSimilarType(RHSType, LHSType))
+ Kind = CK_NoOp;
+ else
+ Kind = CK_BitCast;
return checkPointerTypesForAssignment(*this, LHSType, RHSType);
}
@@ -7825,7 +8014,7 @@ Sema::CheckAssignmentConstraints(QualType LHSType, ExprResult &RHS,
}
// id -> T^
- if (getLangOpts().ObjC1 && RHSType->isObjCIdType()) {
+ if (getLangOpts().ObjC && RHSType->isObjCIdType()) {
Kind = CK_AnyPointerToBlockPointerCast;
return Compatible;
}
@@ -8029,6 +8218,17 @@ Sema::CheckSingleAssignmentConstraints(QualType LHSType, ExprResult &CallerRHS,
ExprResult LocalRHS = CallerRHS;
ExprResult &RHS = ConvertRHS ? CallerRHS : LocalRHS;
+ if (const auto *LHSPtrType = LHSType->getAs<PointerType>()) {
+ if (const auto *RHSPtrType = RHS.get()->getType()->getAs<PointerType>()) {
+ if (RHSPtrType->getPointeeType()->hasAttr(attr::NoDeref) &&
+ !LHSPtrType->getPointeeType()->hasAttr(attr::NoDeref)) {
+ Diag(RHS.get()->getExprLoc(),
+ diag::warn_noderef_to_dereferenceable_pointer)
+ << RHS.get()->getSourceRange();
+ }
+ }
+ }
+
if (getLangOpts().CPlusPlus) {
if (!LHSType->isRecordType() && !LHSType->isAtomicType()) {
// C++ 5.17p3: If the left operand is not of class type, the
@@ -8092,6 +8292,13 @@ Sema::CheckSingleAssignmentConstraints(QualType LHSType, ExprResult &CallerRHS,
return Compatible;
}
+ // OpenCL queue_t type assignment.
+ if (LHSType->isQueueT() && RHS.get()->isNullPointerConstant(
+ Context, Expr::NPC_ValueDependentIsNull)) {
+ RHS = ImpCastExprToType(RHS.get(), LHSType, CK_NullToPointer);
+ return Compatible;
+ }
+
// This check seems unnatural, however it is necessary to ensure the proper
// conversion of functions/arrays. If the conversion were done for all
// DeclExpr's (created by ActOnIdExpression), it would mess up the unary
@@ -8104,16 +8311,6 @@ Sema::CheckSingleAssignmentConstraints(QualType LHSType, ExprResult &CallerRHS,
if (RHS.isInvalid())
return Incompatible;
}
-
- Expr *PRE = RHS.get()->IgnoreParenCasts();
- if (Diagnose && isa<ObjCProtocolExpr>(PRE)) {
- ObjCProtocolDecl *PDecl = cast<ObjCProtocolExpr>(PRE)->getProtocol();
- if (PDecl && !PDecl->hasDefinition()) {
- Diag(PRE->getExprLoc(), diag::warn_atprotocol_protocol) << PDecl;
- Diag(PDecl->getLocation(), diag::note_entity_declared_at) << PDecl;
- }
- }
-
CastKind Kind;
Sema::AssignConvertType result =
CheckAssignmentConstraints(LHSType, RHS, Kind, ConvertRHS);
@@ -8137,8 +8334,8 @@ Sema::CheckSingleAssignmentConstraints(QualType LHSType, ExprResult &CallerRHS,
if (!Diagnose)
return Incompatible;
}
- if (getLangOpts().ObjC1 &&
- (CheckObjCBridgeRelatedConversions(E->getLocStart(), LHSType,
+ if (getLangOpts().ObjC &&
+ (CheckObjCBridgeRelatedConversions(E->getBeginLoc(), LHSType,
E->getType(), E, Diagnose) ||
ConversionToObjCStringLiteralCheck(LHSType, E, Diagnose))) {
if (!Diagnose)
@@ -8152,6 +8349,7 @@ Sema::CheckSingleAssignmentConstraints(QualType LHSType, ExprResult &CallerRHS,
if (ConvertRHS)
RHS = ImpCastExprToType(E, Ty, Kind);
}
+
return result;
}
@@ -8314,8 +8512,8 @@ static bool canConvertIntToOtherIntTy(Sema &S, ExprResult *Int,
// Reject cases where the value of the Int is unknown as that would
// possibly cause truncation, but accept cases where the scalar can be
// demoted without loss of precision.
- llvm::APSInt Result;
- bool CstInt = Int->get()->EvaluateAsInt(Result, S.Context);
+ Expr::EvalResult EVResult;
+ bool CstInt = Int->get()->EvaluateAsInt(EVResult, S.Context);
int Order = S.Context.getIntegerTypeOrder(OtherIntTy, IntTy);
bool IntSigned = IntTy->hasSignedIntegerRepresentation();
bool OtherIntSigned = OtherIntTy->hasSignedIntegerRepresentation();
@@ -8323,6 +8521,7 @@ static bool canConvertIntToOtherIntTy(Sema &S, ExprResult *Int,
if (CstInt) {
// If the scalar is constant and is of a higher order and has more active
// bits that the vector element type, reject it.
+ llvm::APSInt Result = EVResult.Val.getInt();
unsigned NumBits = IntSigned
? (Result.isNegative() ? Result.getMinSignedBits()
: Result.getActiveBits())
@@ -8350,8 +8549,9 @@ static bool canConvertIntTyToFloatTy(Sema &S, ExprResult *Int,
// Determine if the integer constant can be expressed as a floating point
// number of the appropriate type.
- llvm::APSInt Result;
- bool CstInt = Int->get()->EvaluateAsInt(Result, S.Context);
+ Expr::EvalResult EVResult;
+ bool CstInt = Int->get()->EvaluateAsInt(EVResult, S.Context);
+
uint64_t Bits = 0;
if (CstInt) {
// Reject constants that would be truncated if they were converted to
@@ -8359,6 +8559,7 @@ static bool canConvertIntTyToFloatTy(Sema &S, ExprResult *Int,
// FIXME: Ideally the conversion to an APFloat and from an APFloat
// could be avoided if there was a convertFromAPInt method
// which could signal back if implicit truncation occurred.
+ llvm::APSInt Result = EVResult.Val.getInt();
llvm::APFloat Float(S.Context.getFloatTypeSemantics(FloatTy));
Float.convertFromAPInt(Result, IntTy->hasSignedIntegerRepresentation(),
llvm::APFloat::rmTowardZero);
@@ -8668,13 +8869,40 @@ static void checkArithmeticNull(Sema &S, ExprResult &LHS, ExprResult &RHS,
<< LHS.get()->getSourceRange() << RHS.get()->getSourceRange();
}
+static void DiagnoseDivisionSizeofPointer(Sema &S, Expr *LHS, Expr *RHS,
+ SourceLocation Loc) {
+ const auto *LUE = dyn_cast<UnaryExprOrTypeTraitExpr>(LHS);
+ const auto *RUE = dyn_cast<UnaryExprOrTypeTraitExpr>(RHS);
+ if (!LUE || !RUE)
+ return;
+ if (LUE->getKind() != UETT_SizeOf || LUE->isArgumentType() ||
+ RUE->getKind() != UETT_SizeOf)
+ return;
+
+ QualType LHSTy = LUE->getArgumentExpr()->IgnoreParens()->getType();
+ QualType RHSTy;
+
+ if (RUE->isArgumentType())
+ RHSTy = RUE->getArgumentType();
+ else
+ RHSTy = RUE->getArgumentExpr()->IgnoreParens()->getType();
+
+ if (!LHSTy->isPointerType() || RHSTy->isPointerType())
+ return;
+ if (LHSTy->getPointeeType() != RHSTy)
+ return;
+
+ S.Diag(Loc, diag::warn_division_sizeof_ptr) << LHS << LHS->getSourceRange();
+}
+
static void DiagnoseBadDivideOrRemainderValues(Sema& S, ExprResult &LHS,
ExprResult &RHS,
SourceLocation Loc, bool IsDiv) {
// Check for division/remainder by zero.
- llvm::APSInt RHSValue;
+ Expr::EvalResult RHSValue;
if (!RHS.get()->isValueDependent() &&
- RHS.get()->EvaluateAsInt(RHSValue, S.Context) && RHSValue == 0)
+ RHS.get()->EvaluateAsInt(RHSValue, S.Context) &&
+ RHSValue.Val.getInt() == 0)
S.DiagRuntimeBehavior(Loc, RHS.get(),
S.PDiag(diag::warn_remainder_division_by_zero)
<< IsDiv << RHS.get()->getSourceRange());
@@ -8698,8 +8926,10 @@ QualType Sema::CheckMultiplyDivideOperands(ExprResult &LHS, ExprResult &RHS,
if (compType.isNull() || !compType->isArithmeticType())
return InvalidOperands(Loc, LHS, RHS);
- if (IsDiv)
+ if (IsDiv) {
DiagnoseBadDivideOrRemainderValues(*this, LHS, RHS, Loc, IsDiv);
+ DiagnoseDivisionSizeofPointer(*this, LHS.get(), RHS.get(), Loc);
+ }
return compType;
}
@@ -8914,24 +9144,15 @@ static void diagnoseStringPlusInt(Sema &Self, SourceLocation OpLoc,
if (!IsStringPlusInt || IndexExpr->isValueDependent())
return;
- llvm::APSInt index;
- if (IndexExpr->EvaluateAsInt(index, Self.getASTContext())) {
- unsigned StrLenWithNull = StrExpr->getLength() + 1;
- if (index.isNonNegative() &&
- index <= llvm::APSInt(llvm::APInt(index.getBitWidth(), StrLenWithNull),
- index.isUnsigned()))
- return;
- }
-
- SourceRange DiagRange(LHSExpr->getLocStart(), RHSExpr->getLocEnd());
+ SourceRange DiagRange(LHSExpr->getBeginLoc(), RHSExpr->getEndLoc());
Self.Diag(OpLoc, diag::warn_string_plus_int)
<< DiagRange << IndexExpr->IgnoreImpCasts()->getType();
// Only print a fixit for "str" + int, not for int + "str".
if (IndexExpr == RHSExpr) {
- SourceLocation EndLoc = Self.getLocForEndOfToken(RHSExpr->getLocEnd());
+ SourceLocation EndLoc = Self.getLocForEndOfToken(RHSExpr->getEndLoc());
Self.Diag(OpLoc, diag::note_string_plus_scalar_silence)
- << FixItHint::CreateInsertion(LHSExpr->getLocStart(), "&")
+ << FixItHint::CreateInsertion(LHSExpr->getBeginLoc(), "&")
<< FixItHint::CreateReplacement(SourceRange(OpLoc), "[")
<< FixItHint::CreateInsertion(EndLoc, "]");
} else
@@ -8964,7 +9185,7 @@ static void diagnoseStringPlusChar(Sema &Self, SourceLocation OpLoc,
return;
ASTContext &Ctx = Self.getASTContext();
- SourceRange DiagRange(LHSExpr->getLocStart(), RHSExpr->getLocEnd());
+ SourceRange DiagRange(LHSExpr->getBeginLoc(), RHSExpr->getEndLoc());
const QualType CharType = CharExpr->getType();
if (!CharType->isAnyCharacterType() &&
@@ -8979,9 +9200,9 @@ static void diagnoseStringPlusChar(Sema &Self, SourceLocation OpLoc,
// Only print a fixit for str + char, not for char + str.
if (isa<CharacterLiteral>(RHSExpr->IgnoreImpCasts())) {
- SourceLocation EndLoc = Self.getLocForEndOfToken(RHSExpr->getLocEnd());
+ SourceLocation EndLoc = Self.getLocForEndOfToken(RHSExpr->getEndLoc());
Self.Diag(OpLoc, diag::note_string_plus_scalar_silence)
- << FixItHint::CreateInsertion(LHSExpr->getLocStart(), "&")
+ << FixItHint::CreateInsertion(LHSExpr->getBeginLoc(), "&")
<< FixItHint::CreateReplacement(SourceRange(OpLoc), "[")
<< FixItHint::CreateInsertion(EndLoc, "]");
} else {
@@ -9059,10 +9280,11 @@ QualType Sema::CheckAdditionOperands(ExprResult &LHS, ExprResult &RHS,
if (PExp->IgnoreParenCasts()->isNullPointerConstant(
Context, Expr::NPC_ValueDependentIsNotNull)) {
// In C++ adding zero to a null pointer is defined.
- llvm::APSInt KnownVal;
+ Expr::EvalResult KnownVal;
if (!getLangOpts().CPlusPlus ||
(!IExp->isValueDependent() &&
- (!IExp->EvaluateAsInt(KnownVal, Context) || KnownVal != 0))) {
+ (!IExp->EvaluateAsInt(KnownVal, Context) ||
+ KnownVal.Val.getInt() != 0))) {
// Check the conditions to see if this is the 'p = nullptr + n' idiom.
bool IsGNUIdiom = BinaryOperator::isNullPointerArithmeticExtension(
Context, BO_Add, PExp, IExp);
@@ -9137,10 +9359,11 @@ QualType Sema::CheckSubtractionOperands(ExprResult &LHS, ExprResult &RHS,
if (LHS.get()->IgnoreParenCasts()->isNullPointerConstant(Context,
Expr::NPC_ValueDependentIsNotNull)) {
// In C++ adding zero to a null pointer is defined.
- llvm::APSInt KnownVal;
+ Expr::EvalResult KnownVal;
if (!getLangOpts().CPlusPlus ||
(!RHS.get()->isValueDependent() &&
- (!RHS.get()->EvaluateAsInt(KnownVal, Context) || KnownVal != 0))) {
+ (!RHS.get()->EvaluateAsInt(KnownVal, Context) ||
+ KnownVal.Val.getInt() != 0))) {
diagnoseArithmeticOnNullPointer(*this, Loc, LHS.get(), false);
}
}
@@ -9216,11 +9439,12 @@ static void DiagnoseBadShiftValues(Sema& S, ExprResult &LHS, ExprResult &RHS,
if (S.getLangOpts().OpenCL)
return;
- llvm::APSInt Right;
// Check right/shifter operand
+ Expr::EvalResult RHSResult;
if (RHS.get()->isValueDependent() ||
- !RHS.get()->EvaluateAsInt(Right, S.Context))
+ !RHS.get()->EvaluateAsInt(RHSResult, S.Context))
return;
+ llvm::APSInt Right = RHSResult.Val.getInt();
if (Right.isNegative()) {
S.DiagRuntimeBehavior(Loc, RHS.get(),
@@ -9243,11 +9467,12 @@ static void DiagnoseBadShiftValues(Sema& S, ExprResult &LHS, ExprResult &RHS,
// according to C++ has undefined behavior ([expr.shift] 5.8/2). Unsigned
// integers have defined behavior modulo one more than the maximum value
// representable in the result type, so never warn for those.
- llvm::APSInt Left;
+ Expr::EvalResult LHSResult;
if (LHS.get()->isValueDependent() ||
LHSType->hasUnsignedIntegerRepresentation() ||
- !LHS.get()->EvaluateAsInt(Left, S.Context))
+ !LHS.get()->EvaluateAsInt(LHSResult, S.Context))
return;
+ llvm::APSInt Left = LHSResult.Val.getInt();
// If LHS does not have a signed type and non-negative value
// then, the behavior is undefined. Warn about it.
@@ -9653,8 +9878,8 @@ static void diagnoseObjCLiteralComparison(Sema &S, SourceLocation Loc,
if (BinaryOperator::isEqualityOp(Opc) &&
hasIsEqualMethod(S, LHS.get(), RHS.get())) {
- SourceLocation Start = LHS.get()->getLocStart();
- SourceLocation End = S.getLocForEndOfToken(RHS.get()->getLocEnd());
+ SourceLocation Start = LHS.get()->getBeginLoc();
+ SourceLocation End = S.getLocForEndOfToken(RHS.get()->getEndLoc());
CharSourceRange OpRange =
CharSourceRange::getCharRange(Loc, S.getLocForEndOfToken(Loc));
@@ -9686,8 +9911,8 @@ static void diagnoseLogicalNotOnLHSofCheck(Sema &S, ExprResult &LHS,
<< Loc << IsBitwiseOp;
// First note suggest !(x < y)
- SourceLocation FirstOpen = SubExpr->getLocStart();
- SourceLocation FirstClose = RHS.get()->getLocEnd();
+ SourceLocation FirstOpen = SubExpr->getBeginLoc();
+ SourceLocation FirstClose = RHS.get()->getEndLoc();
FirstClose = S.getLocForEndOfToken(FirstClose);
if (FirstClose.isInvalid())
FirstOpen = SourceLocation();
@@ -9697,8 +9922,8 @@ static void diagnoseLogicalNotOnLHSofCheck(Sema &S, ExprResult &LHS,
<< FixItHint::CreateInsertion(FirstClose, ")");
// Second note suggests (!x) < y
- SourceLocation SecondOpen = LHS.get()->getLocStart();
- SourceLocation SecondClose = LHS.get()->getLocEnd();
+ SourceLocation SecondOpen = LHS.get()->getBeginLoc();
+ SourceLocation SecondClose = LHS.get()->getEndLoc();
SecondClose = S.getLocForEndOfToken(SecondClose);
if (SecondClose.isInvalid())
SecondOpen = SourceLocation();
@@ -9734,7 +9959,7 @@ static void diagnoseTautologicalComparison(Sema &S, SourceLocation Loc,
QualType RHSType = RHS->getType();
if (LHSType->hasFloatingRepresentation() ||
(LHSType->isBlockPointerType() && !BinaryOperator::isEqualityOp(Opc)) ||
- LHS->getLocStart().isMacroID() || RHS->getLocStart().isMacroID() ||
+ LHS->getBeginLoc().isMacroID() || RHS->getBeginLoc().isMacroID() ||
S.inTemplateInstantiation())
return;
@@ -9888,7 +10113,7 @@ static bool checkThreeWayNarrowingConversion(Sema &S, QualType ToType, Expr *E,
case NK_Constant_Narrowing:
// Implicit conversion to a narrower type, and the value is not a constant
// expression.
- S.Diag(E->getLocStart(), diag::err_spaceship_argument_narrowing)
+ S.Diag(E->getBeginLoc(), diag::err_spaceship_argument_narrowing)
<< /*Constant*/ 1
<< PreNarrowingValue.getAsString(S.Context, PreNarrowingType) << ToType;
return true;
@@ -9897,7 +10122,7 @@ static bool checkThreeWayNarrowingConversion(Sema &S, QualType ToType, Expr *E,
// Implicit conversion to a narrower type, and the value is not a constant
// expression.
case NK_Type_Narrowing:
- S.Diag(E->getLocStart(), diag::err_spaceship_argument_narrowing)
+ S.Diag(E->getBeginLoc(), diag::err_spaceship_argument_narrowing)
<< /*Constant*/ 0 << FromType << ToType;
// TODO: It's not a constant expression, but what if the user intended it
// to be? Can we produce notes to help them figure out why it isn't?
@@ -9972,9 +10197,9 @@ static QualType checkArithmeticOrEnumeralThreeWayCompare(Sema &S,
assert(Type->isArithmeticType() || Type->isEnumeralType());
bool HasNarrowing = checkThreeWayNarrowingConversion(
- S, Type, LHS.get(), LHSType, LHS.get()->getLocStart());
- HasNarrowing |= checkThreeWayNarrowingConversion(
- S, Type, RHS.get(), RHSType, RHS.get()->getLocStart());
+ S, Type, LHS.get(), LHSType, LHS.get()->getBeginLoc());
+ HasNarrowing |= checkThreeWayNarrowingConversion(S, Type, RHS.get(), RHSType,
+ RHS.get()->getBeginLoc());
if (HasNarrowing)
return QualType();
@@ -10439,6 +10664,14 @@ QualType Sema::CheckCompareOperands(ExprResult &LHS, ExprResult &RHS,
}
if (getLangOpts().OpenCLVersion >= 200) {
+ if (LHSType->isClkEventT() && RHSType->isClkEventT()) {
+ return computeResultTy();
+ }
+
+ if (LHSType->isQueueT() && RHSType->isQueueT()) {
+ return computeResultTy();
+ }
+
if (LHSIsNull && RHSType->isQueueT()) {
LHS = ImpCastExprToType(LHS.get(), RHSType, CK_NullToPointer);
return computeResultTy();
@@ -10609,8 +10842,9 @@ inline QualType Sema::CheckLogicalOperands(ExprResult &LHS, ExprResult &RHS,
// that isn't 0 or 1 (which indicate a potential logical operation that
// happened to fold to true/false) then warn.
// Parens on the RHS are ignored.
- llvm::APSInt Result;
- if (RHS.get()->EvaluateAsInt(Result, Context))
+ Expr::EvalResult EVResult;
+ if (RHS.get()->EvaluateAsInt(EVResult, Context)) {
+ llvm::APSInt Result = EVResult.Val.getInt();
if ((getLangOpts().Bool && !RHS.get()->getType()->isBooleanType() &&
!RHS.get()->getExprLoc().isMacroID()) ||
(Result != 0 && Result != 1)) {
@@ -10627,9 +10861,10 @@ inline QualType Sema::CheckLogicalOperands(ExprResult &LHS, ExprResult &RHS,
// Suggest replacing "Foo() && kNonZero" with "Foo()"
Diag(Loc, diag::note_logical_instead_of_bitwise_remove_constant)
<< FixItHint::CreateRemoval(
- SourceRange(getLocForEndOfToken(LHS.get()->getLocEnd()),
- RHS.get()->getLocEnd()));
+ SourceRange(getLocForEndOfToken(LHS.get()->getEndLoc()),
+ RHS.get()->getEndLoc()));
}
+ }
}
if (!Context.getLangOpts().CPlusPlus) {
@@ -10880,30 +11115,38 @@ static void DiagnoseRecursiveConstFields(Sema &S, const ValueDecl *VD,
const RecordType *Ty,
SourceLocation Loc, SourceRange Range,
OriginalExprKind OEK,
- bool &DiagnosticEmitted,
- bool IsNested = false) {
+ bool &DiagnosticEmitted) {
+ std::vector<const RecordType *> RecordTypeList;
+ RecordTypeList.push_back(Ty);
+ unsigned NextToCheckIndex = 0;
// We walk the record hierarchy breadth-first to ensure that we print
// diagnostics in field nesting order.
- // First, check every field for constness.
- for (const FieldDecl *Field : Ty->getDecl()->fields()) {
- if (Field->getType().isConstQualified()) {
- if (!DiagnosticEmitted) {
- S.Diag(Loc, diag::err_typecheck_assign_const)
- << Range << NestedConstMember << OEK << VD
- << IsNested << Field;
- DiagnosticEmitted = true;
+ while (RecordTypeList.size() > NextToCheckIndex) {
+ bool IsNested = NextToCheckIndex > 0;
+ for (const FieldDecl *Field :
+ RecordTypeList[NextToCheckIndex]->getDecl()->fields()) {
+ // First, check every field for constness.
+ QualType FieldTy = Field->getType();
+ if (FieldTy.isConstQualified()) {
+ if (!DiagnosticEmitted) {
+ S.Diag(Loc, diag::err_typecheck_assign_const)
+ << Range << NestedConstMember << OEK << VD
+ << IsNested << Field;
+ DiagnosticEmitted = true;
+ }
+ S.Diag(Field->getLocation(), diag::note_typecheck_assign_const)
+ << NestedConstMember << IsNested << Field
+ << FieldTy << Field->getSourceRange();
+ }
+
+ // Then we append it to the list to check next in order.
+ FieldTy = FieldTy.getCanonicalType();
+ if (const auto *FieldRecTy = FieldTy->getAs<RecordType>()) {
+ if (llvm::find(RecordTypeList, FieldRecTy) == RecordTypeList.end())
+ RecordTypeList.push_back(FieldRecTy);
}
- S.Diag(Field->getLocation(), diag::note_typecheck_assign_const)
- << NestedConstMember << IsNested << Field
- << Field->getType() << Field->getSourceRange();
}
- }
- // Then, recurse.
- for (const FieldDecl *Field : Ty->getDecl()->fields()) {
- QualType FTy = Field->getType();
- if (const RecordType *FieldRecTy = FTy->getAs<RecordType>())
- DiagnoseRecursiveConstFields(S, VD, FieldRecTy, Loc, Range,
- OEK, DiagnosticEmitted, true);
+ ++NextToCheckIndex;
}
}
@@ -10971,17 +11214,23 @@ static bool CheckForModifiableLvalue(Expr *E, SourceLocation Loc, Sema &S) {
if (var->isARCPseudoStrong() &&
(!var->getTypeSourceInfo() ||
!var->getTypeSourceInfo()->getType().isConstQualified())) {
- // There are two pseudo-strong cases:
+ // There are three pseudo-strong cases:
// - self
ObjCMethodDecl *method = S.getCurMethodDecl();
- if (method && var == method->getSelfDecl())
+ if (method && var == method->getSelfDecl()) {
DiagID = method->isClassMethod()
? diag::err_typecheck_arc_assign_self_class_method
: diag::err_typecheck_arc_assign_self;
+ // - Objective-C externally_retained attribute.
+ } else if (var->hasAttr<ObjCExternallyRetainedAttr>() ||
+ isa<ParmVarDecl>(var)) {
+ DiagID = diag::err_typecheck_arc_assign_externally_retained;
+
// - fast enumeration variables
- else
+ } else {
DiagID = diag::err_typecheck_arr_assign_enumeration;
+ }
SourceRange Assign;
if (Loc != OrigLoc)
@@ -11150,15 +11399,14 @@ QualType Sema::CheckAssignmentOperands(Expr *LHSExpr, ExprResult &RHS,
if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(RHSCheck))
RHSCheck = ICE->getSubExpr();
if (UnaryOperator *UO = dyn_cast<UnaryOperator>(RHSCheck)) {
- if ((UO->getOpcode() == UO_Plus ||
- UO->getOpcode() == UO_Minus) &&
+ if ((UO->getOpcode() == UO_Plus || UO->getOpcode() == UO_Minus) &&
Loc.isFileID() && UO->getOperatorLoc().isFileID() &&
// Only if the two operators are exactly adjacent.
Loc.getLocWithOffset(1) == UO->getOperatorLoc() &&
// And there is a space or other character before the subexpr of the
// unary +/-. We don't want to warn on "x=-1".
- Loc.getLocWithOffset(2) != UO->getSubExpr()->getLocStart() &&
- UO->getSubExpr()->getLocStart().isFileID()) {
+ Loc.getLocWithOffset(2) != UO->getSubExpr()->getBeginLoc() &&
+ UO->getSubExpr()->getBeginLoc().isFileID()) {
Diag(Loc, diag::warn_not_compound_assign)
<< (UO->getOpcode() == UO_Plus ? "+" : "-")
<< SourceRange(UO->getOperatorLoc(), UO->getOperatorLoc());
@@ -11188,7 +11436,7 @@ QualType Sema::CheckAssignmentOperands(Expr *LHSExpr, ExprResult &RHS,
// For ObjCWeak only, we do not warn if the assign is to a non-weak
// variable, which will be valid for the current autorelease scope.
if (!Diags.isIgnored(diag::warn_arc_repeated_use_of_weak,
- RHS.get()->getLocStart()))
+ RHS.get()->getBeginLoc()))
getCurFunction()->markSafeWeakUse(RHS.get());
} else if (getLangOpts().ObjCAutoRefCount || getLangOpts().ObjCWeak) {
@@ -11225,6 +11473,12 @@ static bool IgnoreCommaOperand(const Expr *E) {
if (CE->getCastKind() == CK_ToVoid) {
return true;
}
+
+ // static_cast<void> on a dependent type will not show up as CK_ToVoid.
+ if (CE->getCastKind() == CK_Dependent && E->getType()->isVoidType() &&
+ CE->getSubExpr()->getType()->isDependentType()) {
+ return true;
+ }
}
return false;
@@ -11248,8 +11502,11 @@ void Sema::DiagnoseCommaOperator(const Expr *LHS, SourceLocation Loc) {
// The whitelisted locations are the initialization and increment portions
// of a for loop. The additional checks are on the condition of
// if statements, do/while loops, and for loops.
+ // Differences in scope flags for C89 mode requires the extra logic.
const unsigned ForIncrementFlags =
- Scope::ControlScope | Scope::ContinueScope | Scope::BreakScope;
+ getLangOpts().C99 || getLangOpts().CPlusPlus
+ ? Scope::ControlScope | Scope::ContinueScope | Scope::BreakScope
+ : Scope::ContinueScope | Scope::BreakScope;
const unsigned ForInitFlags = Scope::ControlScope | Scope::DeclScope;
const unsigned ScopeFlags = getCurScope()->getFlags();
if ((ScopeFlags & ForIncrementFlags) == ForIncrementFlags ||
@@ -11269,12 +11526,12 @@ void Sema::DiagnoseCommaOperator(const Expr *LHS, SourceLocation Loc) {
return;
Diag(Loc, diag::warn_comma_operator);
- Diag(LHS->getLocStart(), diag::note_cast_to_void)
+ Diag(LHS->getBeginLoc(), diag::note_cast_to_void)
<< LHS->getSourceRange()
- << FixItHint::CreateInsertion(LHS->getLocStart(),
+ << FixItHint::CreateInsertion(LHS->getBeginLoc(),
LangOpts.CPlusPlus ? "static_cast<void>("
: "(void)(")
- << FixItHint::CreateInsertion(PP.getLocForEndOfToken(LHS->getLocEnd()),
+ << FixItHint::CreateInsertion(PP.getLocForEndOfToken(LHS->getEndLoc()),
")");
}
@@ -11551,7 +11808,7 @@ QualType Sema::CheckAddressOfOperand(ExprResult &OrigOp, SourceLocation OpLoc) {
if (auto *FD = dyn_cast_or_null<FunctionDecl>(dcl))
if (!checkAddressOfFunctionIsAvailable(FD, /*Complain=*/true,
- op->getLocStart()))
+ op->getBeginLoc()))
return QualType();
Expr::LValueClassification lval = op->ClassifyLValue(Context);
@@ -11877,7 +12134,7 @@ static void DiagnoseSelfAssignment(Sema &S, Expr *LHSExpr, Expr *RHSExpr,
/// is usually indicative of introspection within the Objective-C pointer.
static void checkObjCPointerIntrospection(Sema &S, ExprResult &L, ExprResult &R,
SourceLocation OpLoc) {
- if (!S.getLangOpts().ObjC1)
+ if (!S.getLangOpts().ObjC)
return;
const Expr *ObjCPointerExpr = nullptr, *OtherExpr = nullptr;
@@ -12006,7 +12263,7 @@ ExprResult Sema::CreateBuiltinBinOp(SourceLocation OpLoc,
// The meaning of x = {v} [...] is that of x = T(v) [...]. The meaning
// of x = {} is x = T().
InitializationKind Kind = InitializationKind::CreateDirectList(
- RHSExpr->getLocStart(), RHSExpr->getLocStart(), RHSExpr->getLocEnd());
+ RHSExpr->getBeginLoc(), RHSExpr->getBeginLoc(), RHSExpr->getEndLoc());
InitializedEntity Entity =
InitializedEntity::InitializeTemporary(LHSExpr->getType());
InitializationSequence InitSeq(*this, Entity, Kind, RHSExpr);
@@ -12035,7 +12292,7 @@ ExprResult Sema::CreateBuiltinBinOp(SourceLocation OpLoc,
// OpenCLC v2.0 s6.13.11.1 allows atomic variables to be initialized by
// the ATOMIC_VAR_INIT macro.
if (LHSTy->isAtomicType() || RHSTy->isAtomicType()) {
- SourceRange SR(LHSExpr->getLocStart(), RHSExpr->getLocEnd());
+ SourceRange SR(LHSExpr->getBeginLoc(), RHSExpr->getEndLoc());
if (BO_Assign == Opc)
Diag(OpLoc, diag::err_opencl_atomic_init) << 0 << SR;
else
@@ -12197,11 +12454,13 @@ ExprResult Sema::CreateBuiltinBinOp(SourceLocation OpLoc,
&Context.Idents.get("object_setClass"),
SourceLocation(), LookupOrdinaryName);
if (ObjectSetClass && isa<ObjCIsaExpr>(LHS.get())) {
- SourceLocation RHSLocEnd = getLocForEndOfToken(RHS.get()->getLocEnd());
- Diag(LHS.get()->getExprLoc(), diag::warn_objc_isa_assign) <<
- FixItHint::CreateInsertion(LHS.get()->getLocStart(), "object_setClass(") <<
- FixItHint::CreateReplacement(SourceRange(OISA->getOpLoc(), OpLoc), ",") <<
- FixItHint::CreateInsertion(RHSLocEnd, ")");
+ SourceLocation RHSLocEnd = getLocForEndOfToken(RHS.get()->getEndLoc());
+ Diag(LHS.get()->getExprLoc(), diag::warn_objc_isa_assign)
+ << FixItHint::CreateInsertion(LHS.get()->getBeginLoc(),
+ "object_setClass(")
+ << FixItHint::CreateReplacement(SourceRange(OISA->getOpLoc(), OpLoc),
+ ",")
+ << FixItHint::CreateInsertion(RHSLocEnd, ")");
}
else
Diag(LHS.get()->getExprLoc(), diag::warn_objc_isa_assign);
@@ -12258,13 +12517,14 @@ static void DiagnoseBitwisePrecedence(Sema &Self, BinaryOperatorKind Opc,
if (isLeftBitwise || isRightBitwise)
return;
- SourceRange DiagRange = isLeftComp ? SourceRange(LHSExpr->getLocStart(),
- OpLoc)
- : SourceRange(OpLoc, RHSExpr->getLocEnd());
+ SourceRange DiagRange = isLeftComp
+ ? SourceRange(LHSExpr->getBeginLoc(), OpLoc)
+ : SourceRange(OpLoc, RHSExpr->getEndLoc());
StringRef OpStr = isLeftComp ? LHSBO->getOpcodeStr() : RHSBO->getOpcodeStr();
- SourceRange ParensRange = isLeftComp ?
- SourceRange(LHSBO->getRHS()->getLocStart(), RHSExpr->getLocEnd())
- : SourceRange(LHSExpr->getLocStart(), RHSBO->getLHS()->getLocEnd());
+ SourceRange ParensRange =
+ isLeftComp
+ ? SourceRange(LHSBO->getRHS()->getBeginLoc(), RHSExpr->getEndLoc())
+ : SourceRange(LHSExpr->getBeginLoc(), RHSBO->getLHS()->getEndLoc());
Self.Diag(OpLoc, diag::warn_precedence_bitwise_rel)
<< DiagRange << BinaryOperator::getOpcodeStr(Opc) << OpStr;
@@ -12398,10 +12658,9 @@ static void DiagnoseShiftCompare(Sema &S, SourceLocation OpLoc,
S.PDiag(diag::note_precedence_silence)
<< (Kind == OO_LessLess ? "<<" : ">>"),
OCE->getSourceRange());
- SuggestParentheses(S, OpLoc,
- S.PDiag(diag::note_evaluate_comparison_first),
- SourceRange(OCE->getArg(1)->getLocStart(),
- RHSExpr->getLocEnd()));
+ SuggestParentheses(
+ S, OpLoc, S.PDiag(diag::note_evaluate_comparison_first),
+ SourceRange(OCE->getArg(1)->getBeginLoc(), RHSExpr->getEndLoc()));
}
/// DiagnoseBinOpPrecedence - Emit warnings for expressions with tricky
@@ -12643,6 +12902,7 @@ ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc,
break;
case UO_AddrOf:
resultType = CheckAddressOfOperand(Input, OpLoc);
+ CheckAddressOfNoDeref(InputExpr);
RecordModifiableNonNullParam(*this, InputExpr);
break;
case UO_Deref: {
@@ -12807,6 +13067,11 @@ ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc,
auto *UO = new (Context)
UnaryOperator(Input.get(), Opc, resultType, VK, OK, OpLoc, CanOverflow);
+
+ if (Opc == UO_Deref && UO->getType()->hasAttr(attr::NoDeref) &&
+ !isa<ArrayType>(UO->getType().getDesugaredType(Context)))
+ ExprEvalContexts.back().PossibleDerefs.insert(UO);
+
// Convert the result back to a half vector.
if (ConvertHalfVec)
return convertVector(UO, Context.HalfTy, *this);
@@ -13071,9 +13336,9 @@ ExprResult Sema::BuildBuiltinOffsetOf(SourceLocation BuiltinLoc,
// FIXME: An integral constant expression?
if (!Idx->isTypeDependent() && !Idx->isValueDependent() &&
!Idx->getType()->isIntegerType())
- return ExprError(Diag(Idx->getLocStart(),
- diag::err_typecheck_subscript_not_integer)
- << Idx->getSourceRange());
+ return ExprError(
+ Diag(Idx->getBeginLoc(), diag::err_typecheck_subscript_not_integer)
+ << Idx->getSourceRange());
// Record this array index.
Comps.push_back(OffsetOfNode(OC.LocStart, Exprs.size(), OC.LocEnd));
@@ -13294,7 +13559,7 @@ void Sema::ActOnBlockArguments(SourceLocation CaretLoc, Declarator &ParamInfo,
// Drop the parameters.
FunctionProtoType::ExtProtoInfo EPI;
EPI.HasTrailingReturn = false;
- EPI.TypeQuals |= DeclSpec::TQ_const;
+ EPI.TypeQuals.addConst();
T = Context.getFunctionType(Context.DependentTy, None, EPI);
Sig = Context.getTrivialTypeSourceInfo(T);
}
@@ -13365,7 +13630,7 @@ void Sema::ActOnBlockArguments(SourceLocation CaretLoc, Declarator &ParamInfo,
} else if (const FunctionProtoType *Fn = T->getAs<FunctionProtoType>()) {
for (const auto &I : Fn->param_types()) {
ParmVarDecl *Param = BuildParmVarDeclForTypedef(
- CurBlock->TheDecl, ParamInfo.getLocStart(), I);
+ CurBlock->TheDecl, ParamInfo.getBeginLoc(), I);
Params.push_back(Param);
}
}
@@ -13421,6 +13686,7 @@ ExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc,
PopExpressionEvaluationContext();
BlockScopeInfo *BSI = cast<BlockScopeInfo>(FunctionScopes.back());
+ BlockDecl *BD = BSI->TheDecl;
if (BSI->HasImplicitReturnType)
deduceClosureReturnType(*BSI);
@@ -13431,7 +13697,7 @@ ExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc,
if (!BSI->ReturnType.isNull())
RetTy = BSI->ReturnType;
- bool NoReturn = BSI->TheDecl->hasAttr<NoReturnAttr>();
+ bool NoReturn = BD->hasAttr<NoReturnAttr>();
QualType BlockTy;
// Set the captured variables on the block.
@@ -13444,7 +13710,7 @@ ExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc,
Cap.isNested(), Cap.getInitExpr());
Captures.push_back(NewCap);
}
- BSI->TheDecl->setCaptures(Context, Captures, BSI->CXXThisCaptureIndex != 0);
+ BD->setCaptures(Context, Captures, BSI->CXXThisCaptureIndex != 0);
// If the user wrote a function type in some form, try to use that.
if (!BSI->FunctionType.isNull()) {
@@ -13469,7 +13735,7 @@ ExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc,
} else {
const FunctionProtoType *FPT = cast<FunctionProtoType>(FTy);
FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();
- EPI.TypeQuals = 0; // FIXME: silently?
+ EPI.TypeQuals = Qualifiers();
EPI.ExtInfo = Ext;
BlockTy = Context.getFunctionType(RetTy, FPT->getParamTypes(), EPI);
}
@@ -13481,7 +13747,7 @@ ExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc,
BlockTy = Context.getFunctionType(RetTy, None, EPI);
}
- DiagnoseUnusedParameters(BSI->TheDecl->parameters());
+ DiagnoseUnusedParameters(BD->parameters());
BlockTy = Context.getBlockPointerType(BlockTy);
// If needed, diagnose invalid gotos and switches in the block.
@@ -13489,19 +13755,19 @@ ExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc,
!PP.isCodeCompletionEnabled())
DiagnoseInvalidJumps(cast<CompoundStmt>(Body));
- BSI->TheDecl->setBody(cast<CompoundStmt>(Body));
+ BD->setBody(cast<CompoundStmt>(Body));
if (Body && getCurFunction()->HasPotentialAvailabilityViolations)
- DiagnoseUnguardedAvailabilityViolations(BSI->TheDecl);
+ DiagnoseUnguardedAvailabilityViolations(BD);
// Try to apply the named return value optimization. We have to check again
// if we can do this, though, because blocks keep return statements around
// to deduce an implicit return type.
if (getLangOpts().CPlusPlus && RetTy->isRecordType() &&
- !BSI->TheDecl->isDependentContext())
+ !BD->isDependentContext())
computeNRVO(Body, BSI);
- BlockExpr *Result = new (Context) BlockExpr(BSI->TheDecl, BlockTy);
+ BlockExpr *Result = new (Context) BlockExpr(BD, BlockTy);
AnalysisBasedWarnings::Policy WP = AnalysisWarnings.getDefaultPolicy();
PopFunctionScopeInfo(&WP, Result->getBlockDecl(), Result);
@@ -13523,6 +13789,9 @@ ExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc,
}
}
+ if (getCurFunction())
+ getCurFunction()->addBlock(BD);
+
return Result;
}
@@ -13544,7 +13813,7 @@ ExprResult Sema::BuildVAArgExpr(SourceLocation BuiltinLoc,
if (const FunctionDecl *F = dyn_cast<FunctionDecl>(CurContext)) {
CUDAFunctionTarget T = IdentifyCUDATarget(F);
if (T == CFT_Global || T == CFT_Device || T == CFT_HostDevice)
- return ExprError(Diag(E->getLocStart(), diag::err_va_arg_in_device));
+ return ExprError(Diag(E->getBeginLoc(), diag::err_va_arg_in_device));
}
}
@@ -13594,9 +13863,10 @@ ExprResult Sema::BuildVAArgExpr(SourceLocation BuiltinLoc,
if (!IsMS && !E->isTypeDependent() &&
!Context.hasSameType(VaListType, E->getType()))
- return ExprError(Diag(E->getLocStart(),
- diag::err_first_argument_to_va_arg_not_of_type_va_list)
- << OrigExpr->getType() << E->getSourceRange());
+ return ExprError(
+ Diag(E->getBeginLoc(),
+ diag::err_first_argument_to_va_arg_not_of_type_va_list)
+ << OrigExpr->getType() << E->getSourceRange());
if (!TInfo->getType()->isDependentType()) {
if (RequireCompleteType(TInfo->getTypeLoc().getBeginLoc(), TInfo->getType(),
@@ -13661,7 +13931,7 @@ ExprResult Sema::ActOnGNUNullExpr(SourceLocation TokenLoc) {
bool Sema::ConversionToObjCStringLiteralCheck(QualType DstType, Expr *&Exp,
bool Diagnose) {
- if (!getLangOpts().ObjC1)
+ if (!getLangOpts().ObjC)
return false;
const ObjCObjectPointerType *PT = DstType->getAs<ObjCObjectPointerType>();
@@ -13687,9 +13957,9 @@ bool Sema::ConversionToObjCStringLiteralCheck(QualType DstType, Expr *&Exp,
if (!SL || !SL->isAscii())
return false;
if (Diagnose) {
- Diag(SL->getLocStart(), diag::err_missing_atsign_prefix)
- << FixItHint::CreateInsertion(SL->getLocStart(), "@");
- Exp = BuildObjCStringLiteral(SL->getLocStart(), SL).get();
+ Diag(SL->getBeginLoc(), diag::err_missing_atsign_prefix)
+ << FixItHint::CreateInsertion(SL->getBeginLoc(), "@");
+ Exp = BuildObjCStringLiteral(SL->getBeginLoc(), SL).get();
}
return true;
}
@@ -13710,7 +13980,7 @@ static bool maybeDiagnoseAssignmentToFunction(Sema &S, QualType DstType,
return !S.checkAddressOfFunctionIsAvailable(FD,
/*Complain=*/true,
- SrcExpr->getLocStart());
+ SrcExpr->getBeginLoc());
}
bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy,
@@ -13963,7 +14233,7 @@ ExprResult
Sema::VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result,
VerifyICEDiagnoser &Diagnoser,
bool AllowFold) {
- SourceLocation DiagLoc = E->getLocStart();
+ SourceLocation DiagLoc = E->getBeginLoc();
if (getLangOpts().CPlusPlus11) {
// C++11 [expr.const]p5:
@@ -14030,11 +14300,14 @@ Sema::VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result,
return ExprError();
}
+ if (!isa<ConstantExpr>(E))
+ E = ConstantExpr::Create(Context, E);
+
// Circumvent ICE checking in C++11 to avoid evaluating the expression twice
// in the non-ICE case.
if (!getLangOpts().CPlusPlus11 && E->isIntegerConstantExpr(Context)) {
if (Result)
- *Result = E->EvaluateKnownConstInt(Context);
+ *Result = E->EvaluateKnownConstIntCheckOverflow(Context);
return E;
}
@@ -14165,6 +14438,51 @@ Sema::PushExpressionEvaluationContext(
PushExpressionEvaluationContext(NewContext, ClosureContextDecl, ExprContext);
}
+namespace {
+
+const DeclRefExpr *CheckPossibleDeref(Sema &S, const Expr *PossibleDeref) {
+ PossibleDeref = PossibleDeref->IgnoreParenImpCasts();
+ if (const auto *E = dyn_cast<UnaryOperator>(PossibleDeref)) {
+ if (E->getOpcode() == UO_Deref)
+ return CheckPossibleDeref(S, E->getSubExpr());
+ } else if (const auto *E = dyn_cast<ArraySubscriptExpr>(PossibleDeref)) {
+ return CheckPossibleDeref(S, E->getBase());
+ } else if (const auto *E = dyn_cast<MemberExpr>(PossibleDeref)) {
+ return CheckPossibleDeref(S, E->getBase());
+ } else if (const auto E = dyn_cast<DeclRefExpr>(PossibleDeref)) {
+ QualType Inner;
+ QualType Ty = E->getType();
+ if (const auto *Ptr = Ty->getAs<PointerType>())
+ Inner = Ptr->getPointeeType();
+ else if (const auto *Arr = S.Context.getAsArrayType(Ty))
+ Inner = Arr->getElementType();
+ else
+ return nullptr;
+
+ if (Inner->hasAttr(attr::NoDeref))
+ return E;
+ }
+ return nullptr;
+}
+
+} // namespace
+
+void Sema::WarnOnPendingNoDerefs(ExpressionEvaluationContextRecord &Rec) {
+ for (const Expr *E : Rec.PossibleDerefs) {
+ const DeclRefExpr *DeclRef = CheckPossibleDeref(*this, E);
+ if (DeclRef) {
+ const ValueDecl *Decl = DeclRef->getDecl();
+ Diag(E->getExprLoc(), diag::warn_dereference_of_noderef_type)
+ << Decl->getName() << E->getSourceRange();
+ Diag(Decl->getLocation(), diag::note_previous_decl) << Decl->getName();
+ } else {
+ Diag(E->getExprLoc(), diag::warn_dereference_of_noderef_type_no_decl)
+ << E->getSourceRange();
+ }
+ }
+ Rec.PossibleDerefs.clear();
+}
+
void Sema::PopExpressionEvaluationContext() {
ExpressionEvaluationContextRecord& Rec = ExprEvalContexts.back();
unsigned NumTypos = Rec.NumTypos;
@@ -14193,7 +14511,7 @@ void Sema::PopExpressionEvaluationContext() {
llvm_unreachable("Couldn't infer lambda error message.");
for (const auto *L : Rec.Lambdas)
- Diag(L->getLocStart(), D);
+ Diag(L->getBeginLoc(), D);
} else {
// Mark the capture expressions odr-used. This was deferred
// during lambda expression creation.
@@ -14204,6 +14522,8 @@ void Sema::PopExpressionEvaluationContext() {
}
}
+ WarnOnPendingNoDerefs(Rec);
+
// When are coming out of an unevaluated context, clear out any
// temporaries that we may have created as part of the evaluation of
// the expression in that context: they aren't relevant because they
@@ -14224,11 +14544,8 @@ void Sema::PopExpressionEvaluationContext() {
// Pop the current expression evaluation context off the stack.
ExprEvalContexts.pop_back();
- if (!ExprEvalContexts.empty())
- ExprEvalContexts.back().NumTypos += NumTypos;
- else
- assert(NumTypos == 0 && "There are outstanding typos after popping the "
- "last ExpressionEvaluationContextRecord");
+ // The global expression evaluation context record is never popped.
+ ExprEvalContexts.back().NumTypos += NumTypos;
}
void Sema::DiscardCleanupsInEvaluationContext() {
@@ -14240,6 +14557,10 @@ void Sema::DiscardCleanupsInEvaluationContext() {
}
ExprResult Sema::HandleExprEvaluationContextForTypeof(Expr *E) {
+ ExprResult Result = CheckPlaceholderExpr(E);
+ if (Result.isInvalid())
+ return ExprError();
+ E = Result.get();
if (!E->getType()->isVariablyModifiedType())
return E;
return TransformToPotentiallyEvaluated(E);
@@ -14641,8 +14962,10 @@ static bool captureInBlock(BlockScopeInfo *BSI, VarDecl *Var,
Expr *CopyExpr = nullptr;
bool ByRef = false;
- // Blocks are not allowed to capture arrays.
- if (CaptureType->isArrayType()) {
+ // Blocks are not allowed to capture arrays, excepting OpenCL.
+ // OpenCL v2.0 s1.12.5 (revision 40): arrays are captured by reference
+ // (decayed to pointers).
+ if (!S.getLangOpts().OpenCL && CaptureType->isArrayType()) {
if (BuildAndDiagnose) {
S.Diag(Loc, diag::err_ref_array_type);
S.Diag(Var->getLocation(), diag::note_previous_decl)
@@ -14665,15 +14988,15 @@ static bool captureInBlock(BlockScopeInfo *BSI, VarDecl *Var,
// Warn about implicitly autoreleasing indirect parameters captured by blocks.
if (const auto *PT = CaptureType->getAs<PointerType>()) {
// This function finds out whether there is an AttributedType of kind
- // attr_objc_ownership in Ty. The existence of AttributedType of kind
- // attr_objc_ownership implies __autoreleasing was explicitly specified
+ // attr::ObjCOwnership in Ty. The existence of AttributedType of kind
+ // attr::ObjCOwnership implies __autoreleasing was explicitly specified
// rather than being added implicitly by the compiler.
auto IsObjCOwnershipAttributedType = [](QualType Ty) {
while (const auto *AttrTy = Ty->getAs<AttributedType>()) {
- if (AttrTy->getAttrKind() == AttributedType::attr_objc_ownership)
+ if (AttrTy->getAttrKind() == attr::ObjCOwnership)
return true;
- // Peel off AttributedTypes that are not of kind objc_ownership.
+ // Peel off AttributedTypes that are not of kind ObjCOwnership.
Ty = AttrTy->getModifiedType();
}
@@ -14722,9 +15045,8 @@ static bool captureInBlock(BlockScopeInfo *BSI, VarDecl *Var,
// According to the blocks spec, the capture of a variable from
// the stack requires a const copy constructor. This is not true
// of the copy/move done to move a __block variable to the heap.
- Expr *DeclRef = new (S.Context) DeclRefExpr(Var, Nested,
- DeclRefType.withConst(),
- VK_LValue, Loc);
+ Expr *DeclRef = new (S.Context) DeclRefExpr(
+ S.Context, Var, Nested, DeclRefType.withConst(), VK_LValue, Loc);
ExprResult Result
= S.PerformCopyInitialization(
@@ -14800,8 +15122,8 @@ static bool captureInCapturedRegion(CapturedRegionScopeInfo *RSI,
if (S.getLangOpts().OpenMP && RSI->CapRegionKind == CR_OpenMP)
S.setOpenMPCaptureKind(Field, Var, RSI->OpenMPLevel);
- CopyExpr = new (S.Context) DeclRefExpr(Var, RefersToCapturedVariable,
- DeclRefType, VK_LValue, Loc);
+ CopyExpr = new (S.Context) DeclRefExpr(
+ S.Context, Var, RefersToCapturedVariable, DeclRefType, VK_LValue, Loc);
Var->setReferenced(true);
Var->markUsed(S.Context);
}
@@ -14828,6 +15150,21 @@ static void addAsFieldToClosureType(Sema &S, LambdaScopeInfo *LSI,
= FieldDecl::Create(S.Context, Lambda, Loc, Loc, nullptr, FieldType,
S.Context.getTrivialTypeSourceInfo(FieldType, Loc),
nullptr, false, ICIS_NoInit);
+ // If the variable being captured has an invalid type, mark the lambda class
+ // as invalid as well.
+ if (!FieldType->isDependentType()) {
+ if (S.RequireCompleteType(Loc, FieldType, diag::err_field_incomplete)) {
+ Lambda->setInvalidDecl();
+ Field->setInvalidDecl();
+ } else {
+ NamedDecl *Def;
+ FieldType->isIncompleteType(&Def);
+ if (Def && Def->isInvalidDecl()) {
+ Lambda->setInvalidDecl();
+ Field->setInvalidDecl();
+ }
+ }
+ }
Field->setImplicit(true);
Field->setAccess(AS_private);
Lambda->addDecl(Field);
@@ -15023,7 +15360,7 @@ bool Sema::tryCaptureVariable(
Diag(ExprLoc, diag::err_lambda_impcap) << Var->getDeclName();
Diag(Var->getLocation(), diag::note_previous_decl)
<< Var->getDeclName();
- Diag(LSI->Lambda->getLocStart(), diag::note_lambda_decl);
+ Diag(LSI->Lambda->getBeginLoc(), diag::note_lambda_decl);
} else
diagnoseUncapturableValueReference(*this, ExprLoc, Var, DC);
}
@@ -15077,7 +15414,7 @@ bool Sema::tryCaptureVariable(
Diag(Var->getLocation(), diag::note_previous_decl)
<< Var->getDeclName();
if (cast<LambdaScopeInfo>(CSI)->Lambda)
- Diag(cast<LambdaScopeInfo>(CSI)->Lambda->getLocStart(),
+ Diag(cast<LambdaScopeInfo>(CSI)->Lambda->getBeginLoc(),
diag::note_lambda_decl);
// FIXME: If we error out because an outer lambda can not implicitly
// capture a variable that an inner lambda explicitly captures, we
@@ -15435,8 +15772,8 @@ void Sema::MarkMemberReferenced(MemberExpr *E) {
if (Method->isPure())
MightBeOdrUse = false;
}
- SourceLocation Loc = E->getMemberLoc().isValid() ?
- E->getMemberLoc() : E->getLocStart();
+ SourceLocation Loc =
+ E->getMemberLoc().isValid() ? E->getMemberLoc() : E->getBeginLoc();
MarkExprReferenced(*this, Loc, E->getMemberDecl(), E, MightBeOdrUse);
}
@@ -15532,34 +15869,34 @@ namespace {
}
void VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
- S.MarkFunctionReferenced(E->getLocStart(),
- const_cast<CXXDestructorDecl*>(E->getTemporary()->getDestructor()));
+ S.MarkFunctionReferenced(
+ E->getBeginLoc(),
+ const_cast<CXXDestructorDecl *>(E->getTemporary()->getDestructor()));
Visit(E->getSubExpr());
}
void VisitCXXNewExpr(CXXNewExpr *E) {
if (E->getOperatorNew())
- S.MarkFunctionReferenced(E->getLocStart(), E->getOperatorNew());
+ S.MarkFunctionReferenced(E->getBeginLoc(), E->getOperatorNew());
if (E->getOperatorDelete())
- S.MarkFunctionReferenced(E->getLocStart(), E->getOperatorDelete());
+ S.MarkFunctionReferenced(E->getBeginLoc(), E->getOperatorDelete());
Inherited::VisitCXXNewExpr(E);
}
void VisitCXXDeleteExpr(CXXDeleteExpr *E) {
if (E->getOperatorDelete())
- S.MarkFunctionReferenced(E->getLocStart(), E->getOperatorDelete());
+ S.MarkFunctionReferenced(E->getBeginLoc(), E->getOperatorDelete());
QualType Destroyed = S.Context.getBaseElementType(E->getDestroyedType());
if (const RecordType *DestroyedRec = Destroyed->getAs<RecordType>()) {
CXXRecordDecl *Record = cast<CXXRecordDecl>(DestroyedRec->getDecl());
- S.MarkFunctionReferenced(E->getLocStart(),
- S.LookupDestructor(Record));
+ S.MarkFunctionReferenced(E->getBeginLoc(), S.LookupDestructor(Record));
}
Inherited::VisitCXXDeleteExpr(E);
}
void VisitCXXConstructExpr(CXXConstructExpr *E) {
- S.MarkFunctionReferenced(E->getLocStart(), E->getConstructor());
+ S.MarkFunctionReferenced(E->getBeginLoc(), E->getConstructor());
Inherited::VisitCXXConstructExpr(E);
}
@@ -15730,7 +16067,7 @@ void Sema::DiagnoseAssignmentAsCondition(Expr *E) {
Diag(Loc, diagnostic) << E->getSourceRange();
- SourceLocation Open = E->getLocStart();
+ SourceLocation Open = E->getBeginLoc();
SourceLocation Close = getLocForEndOfToken(E->getSourceRange().getEnd());
Diag(Loc, diag::note_condition_assign_silence)
<< FixItHint::CreateInsertion(Open, "(")
@@ -15748,7 +16085,7 @@ void Sema::DiagnoseAssignmentAsCondition(Expr *E) {
/// that the user intended an assignment used as condition.
void Sema::DiagnoseEqualityWithExtraParens(ParenExpr *ParenE) {
// Don't warn if the parens came from a macro.
- SourceLocation parenLoc = ParenE->getLocStart();
+ SourceLocation parenLoc = ParenE->getBeginLoc();
if (parenLoc.isInvalid() || parenLoc.isMacroID())
return;
// Don't warn for dependent expressions.
@@ -16211,7 +16548,7 @@ ExprResult RebuildUnknownAnyExpr::resolveDecl(Expr *E, ValueDecl *VD) {
DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E);
if (DRE && Proto && Proto->getParamTypes().empty() && Proto->isVariadic()) {
SourceLocation Loc = FD->getLocation();
- FunctionDecl *NewFD = FunctionDecl::Create(FD->getASTContext(),
+ FunctionDecl *NewFD = FunctionDecl::Create(S.Context,
FD->getDeclContext(),
Loc, Loc, FD->getNameInfo().getName(),
DestType, FD->getTypeSourceInfo(),
@@ -16439,25 +16776,29 @@ ExprResult Sema::CheckPlaceholderExpr(Expr *E) {
auto *FD = cast<FunctionDecl>(DRE->getDecl());
if (FD->getBuiltinID() == Builtin::BI__noop) {
E = ImpCastExprToType(E, Context.getPointerType(FD->getType()),
- CK_BuiltinFnToFnPtr).get();
- return new (Context) CallExpr(Context, E, None, Context.IntTy,
- VK_RValue, SourceLocation());
+ CK_BuiltinFnToFnPtr)
+ .get();
+ return CallExpr::Create(Context, E, /*Args=*/{}, Context.IntTy,
+ VK_RValue, SourceLocation());
}
}
- Diag(E->getLocStart(), diag::err_builtin_fn_use);
+ Diag(E->getBeginLoc(), diag::err_builtin_fn_use);
return ExprError();
}
// Expressions of unknown type.
case BuiltinType::OMPArraySection:
- Diag(E->getLocStart(), diag::err_omp_array_section_use);
+ Diag(E->getBeginLoc(), diag::err_omp_array_section_use);
return ExprError();
// Everything else should be impossible.
#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
case BuiltinType::Id:
#include "clang/Basic/OpenCLImageTypes.def"
+#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
+ case BuiltinType::Id:
+#include "clang/Basic/OpenCLExtensionTypes.def"
#define BUILTIN_TYPE(Id, SingletonId) case BuiltinType::Id:
#define PLACEHOLDER_TYPE(Id, SingletonId)
#include "clang/AST/BuiltinTypes.def"