aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Sema/SemaInit.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Sema/SemaInit.cpp')
-rw-r--r--clang/lib/Sema/SemaInit.cpp156
1 files changed, 109 insertions, 47 deletions
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index 785637761e71..eb07de65d266 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -17,6 +17,7 @@
#include "clang/AST/ExprOpenMP.h"
#include "clang/AST/TypeLoc.h"
#include "clang/Basic/CharInfo.h"
+#include "clang/Basic/SourceManager.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Sema/Designator.h"
#include "clang/Sema/Initialization.h"
@@ -1092,7 +1093,7 @@ void InitListChecker::CheckImplicitInitList(const InitializedEntity &Entity,
auto *CXXRD = T->getAsCXXRecordDecl();
if (!VerifyOnly && CXXRD && CXXRD->hasUserDeclaredConstructor()) {
SemaRef.Diag(StructuredSubobjectInitList->getBeginLoc(),
- diag::warn_cxx2a_compat_aggregate_init_with_ctors)
+ diag::warn_cxx20_compat_aggregate_init_with_ctors)
<< StructuredSubobjectInitList->getSourceRange() << T;
}
}
@@ -1118,14 +1119,14 @@ static void warnBracedScalarInit(Sema &S, const InitializedEntity &Entity,
case InitializedEntity::EK_Parameter_CF_Audited:
case InitializedEntity::EK_Result:
// Extra braces here are suspicious.
- DiagID = diag::warn_braces_around_scalar_init;
+ DiagID = diag::warn_braces_around_init;
break;
case InitializedEntity::EK_Member:
// Warn on aggregate initialization but not on ctor init list or
// default member initializer.
if (Entity.getParent())
- DiagID = diag::warn_braces_around_scalar_init;
+ DiagID = diag::warn_braces_around_init;
break;
case InitializedEntity::EK_Variable:
@@ -1156,9 +1157,9 @@ static void warnBracedScalarInit(Sema &S, const InitializedEntity &Entity,
if (DiagID) {
S.Diag(Braces.getBegin(), DiagID)
- << Braces
- << FixItHint::CreateRemoval(Braces.getBegin())
- << FixItHint::CreateRemoval(Braces.getEnd());
+ << Entity.getType()->isSizelessBuiltinType() << Braces
+ << FixItHint::CreateRemoval(Braces.getBegin())
+ << FixItHint::CreateRemoval(Braces.getEnd());
}
}
@@ -1202,6 +1203,12 @@ void InitListChecker::CheckExplicitInitList(const InitializedEntity &Entity,
: diag::ext_excess_initializers_in_char_array_initializer;
SemaRef.Diag(IList->getInit(Index)->getBeginLoc(), DK)
<< IList->getInit(Index)->getSourceRange();
+ } else if (T->isSizelessBuiltinType()) {
+ unsigned DK = ExtraInitsIsError
+ ? diag::err_excess_initializers_for_sizeless_type
+ : diag::ext_excess_initializers_for_sizeless_type;
+ SemaRef.Diag(IList->getInit(Index)->getBeginLoc(), DK)
+ << T << IList->getInit(Index)->getSourceRange();
} else {
int initKind = T->isArrayType() ? 0 :
T->isVectorType() ? 1 :
@@ -1235,7 +1242,7 @@ void InitListChecker::CheckExplicitInitList(const InitializedEntity &Entity,
if (!HasEquivCtor) {
SemaRef.Diag(IList->getBeginLoc(),
- diag::warn_cxx2a_compat_aggregate_init_with_ctors)
+ diag::warn_cxx20_compat_aggregate_init_with_ctors)
<< IList->getSourceRange() << T;
}
}
@@ -1294,7 +1301,8 @@ void InitListChecker::CheckListElementTypes(const InitializedEntity &Entity,
if (!VerifyOnly)
SemaRef.Diag(IList->getBeginLoc(), diag::err_init_objc_class) << DeclType;
hadError = true;
- } else if (DeclType->isOCLIntelSubgroupAVCType()) {
+ } else if (DeclType->isOCLIntelSubgroupAVCType() ||
+ DeclType->isSizelessBuiltinType()) {
// Checks for scalar type are sufficient for these types too.
CheckScalarType(Entity, IList, DeclType, Index, StructuredList,
StructuredIndex);
@@ -1507,12 +1515,20 @@ void InitListChecker::CheckScalarType(const InitializedEntity &Entity,
InitListExpr *StructuredList,
unsigned &StructuredIndex) {
if (Index >= IList->getNumInits()) {
- if (!VerifyOnly)
- SemaRef.Diag(IList->getBeginLoc(),
- SemaRef.getLangOpts().CPlusPlus11
- ? diag::warn_cxx98_compat_empty_scalar_initializer
- : diag::err_empty_scalar_initializer)
- << IList->getSourceRange();
+ if (!VerifyOnly) {
+ if (DeclType->isSizelessBuiltinType())
+ SemaRef.Diag(IList->getBeginLoc(),
+ SemaRef.getLangOpts().CPlusPlus11
+ ? diag::warn_cxx98_compat_empty_sizeless_initializer
+ : diag::err_empty_sizeless_initializer)
+ << DeclType << IList->getSourceRange();
+ else
+ SemaRef.Diag(IList->getBeginLoc(),
+ SemaRef.getLangOpts().CPlusPlus11
+ ? diag::warn_cxx98_compat_empty_scalar_initializer
+ : diag::err_empty_scalar_initializer)
+ << IList->getSourceRange();
+ }
hadError = !SemaRef.getLangOpts().CPlusPlus11;
++Index;
++StructuredIndex;
@@ -1524,17 +1540,18 @@ void InitListChecker::CheckScalarType(const InitializedEntity &Entity,
// FIXME: This is invalid, and accepting it causes overload resolution
// to pick the wrong overload in some corner cases.
if (!VerifyOnly)
- SemaRef.Diag(SubIList->getBeginLoc(),
- diag::ext_many_braces_around_scalar_init)
- << SubIList->getSourceRange();
+ SemaRef.Diag(SubIList->getBeginLoc(), diag::ext_many_braces_around_init)
+ << DeclType->isSizelessBuiltinType() << SubIList->getSourceRange();
CheckScalarType(Entity, SubIList, DeclType, Index, StructuredList,
StructuredIndex);
return;
} else if (isa<DesignatedInitExpr>(expr)) {
if (!VerifyOnly)
- SemaRef.Diag(expr->getBeginLoc(), diag::err_designator_for_scalar_init)
- << DeclType << expr->getSourceRange();
+ SemaRef.Diag(expr->getBeginLoc(),
+ diag::err_designator_for_scalar_or_sizeless_init)
+ << DeclType->isSizelessBuiltinType() << DeclType
+ << expr->getSourceRange();
hadError = true;
++Index;
++StructuredIndex;
@@ -1621,7 +1638,7 @@ void InitListChecker::CheckReferenceType(const InitializedEntity &Entity,
expr = Result.getAs<Expr>();
// FIXME: Why are we updating the syntactic init list?
- if (!VerifyOnly)
+ if (!VerifyOnly && expr)
IList->setInit(Index, expr);
if (hadError)
@@ -3477,6 +3494,7 @@ bool InitializationSequence::isAmbiguous() const {
case FK_NonConstLValueReferenceBindingToTemporary:
case FK_NonConstLValueReferenceBindingToBitfield:
case FK_NonConstLValueReferenceBindingToVectorElement:
+ case FK_NonConstLValueReferenceBindingToMatrixElement:
case FK_NonConstLValueReferenceBindingToUnrelated:
case FK_RValueReferenceBindingToLValue:
case FK_ReferenceAddrspaceMismatchTemporary:
@@ -4420,16 +4438,20 @@ static void TryListInitialization(Sema &S,
// direct-list-initialization and copy-initialization otherwise.
// We can't use InitListChecker for this, because it always performs
// copy-initialization. This only matters if we might use an 'explicit'
- // conversion operator, so we only need to handle the cases where the source
- // is of record type.
- if (InitList->getInit(0)->getType()->isRecordType()) {
+ // conversion operator, or for the special case conversion of nullptr_t to
+ // bool, so we only need to handle those cases.
+ //
+ // FIXME: Why not do this in all cases?
+ Expr *Init = InitList->getInit(0);
+ if (Init->getType()->isRecordType() ||
+ (Init->getType()->isNullPtrType() && DestType->isBooleanType())) {
InitializationKind SubKind =
Kind.getKind() == InitializationKind::IK_DirectList
? InitializationKind::CreateDirect(Kind.getLocation(),
InitList->getLBraceLoc(),
InitList->getRBraceLoc())
: Kind;
- Expr *SubInit[1] = { InitList->getInit(0) };
+ Expr *SubInit[1] = { Init };
Sequence.InitializeFrom(S, Entity, SubKind, SubInit,
/*TopLevelOfInitList*/true,
TreatUnavailableAsInvalid);
@@ -4666,10 +4688,14 @@ static void TryReferenceInitialization(Sema &S,
/// which a reference can never bind). Attempting to bind a reference to
/// such a glvalue will always create a temporary.
static bool isNonReferenceableGLValue(Expr *E) {
- return E->refersToBitField() || E->refersToVectorElement();
+ return E->refersToBitField() || E->refersToVectorElement() ||
+ E->refersToMatrixElement();
}
/// Reference initialization without resolving overloaded functions.
+///
+/// We also can get here in C if we call a builtin which is declared as
+/// a function with a parameter of reference type (such as __builtin_va_end()).
static void TryReferenceInitializationCore(Sema &S,
const InitializedEntity &Entity,
const InitializationKind &Kind,
@@ -4746,15 +4772,20 @@ static void TryReferenceInitializationCore(Sema &S,
// an rvalue. DR1287 removed the "implicitly" here.
if (RefRelationship == Sema::Ref_Incompatible && T2->isRecordType() &&
(isLValueRef || InitCategory.isRValue())) {
- ConvOvlResult = TryRefInitWithConversionFunction(
- S, Entity, Kind, Initializer, /*AllowRValues*/ isRValueRef,
- /*IsLValueRef*/ isLValueRef, Sequence);
- if (ConvOvlResult == OR_Success)
- return;
- if (ConvOvlResult != OR_No_Viable_Function)
- Sequence.SetOverloadFailure(
- InitializationSequence::FK_ReferenceInitOverloadFailed,
- ConvOvlResult);
+ if (S.getLangOpts().CPlusPlus) {
+ // Try conversion functions only for C++.
+ ConvOvlResult = TryRefInitWithConversionFunction(
+ S, Entity, Kind, Initializer, /*AllowRValues*/ isRValueRef,
+ /*IsLValueRef*/ isLValueRef, Sequence);
+ if (ConvOvlResult == OR_Success)
+ return;
+ if (ConvOvlResult != OR_No_Viable_Function)
+ Sequence.SetOverloadFailure(
+ InitializationSequence::FK_ReferenceInitOverloadFailed,
+ ConvOvlResult);
+ } else {
+ ConvOvlResult = OR_No_Viable_Function;
+ }
}
}
@@ -4787,6 +4818,9 @@ static void TryReferenceInitializationCore(Sema &S,
else if (Initializer->refersToVectorElement())
FK = InitializationSequence::
FK_NonConstLValueReferenceBindingToVectorElement;
+ else if (Initializer->refersToMatrixElement())
+ FK = InitializationSequence::
+ FK_NonConstLValueReferenceBindingToMatrixElement;
else
llvm_unreachable("unexpected kind of compatible initializer");
break;
@@ -4924,7 +4958,7 @@ static void TryReferenceInitializationCore(Sema &S,
ImplicitConversionSequence ICS
= S.TryImplicitConversion(Initializer, TempEntity.getType(),
/*SuppressUserConversions=*/false,
- /*AllowExplicit=*/false,
+ Sema::AllowedExplicit::None,
/*FIXME:InOverloadResolution=*/false,
/*CStyle=*/Kind.isCStyleOrFunctionalCast(),
/*AllowObjCWritebackConversion=*/false);
@@ -5620,7 +5654,7 @@ void InitializationSequence::InitializeFrom(Sema &S,
if (S.CheckObjCBridgeRelatedConversions(Initializer->getBeginLoc(),
DestType, Initializer->getType(),
Initializer) ||
- S.ConversionToObjCStringLiteralCheck(DestType, Initializer))
+ S.CheckConversionToObjCLiteral(DestType, Initializer))
Args[0] = Initializer;
}
if (!isa<InitListExpr>(Initializer))
@@ -5854,6 +5888,19 @@ void InitializationSequence::InitializeFrom(Sema &S,
return;
}
+ // - Otherwise, if the initialization is direct-initialization, the source
+ // type is std::nullptr_t, and the destination type is bool, the initial
+ // value of the object being initialized is false.
+ if (!SourceType.isNull() && SourceType->isNullPtrType() &&
+ DestType->isBooleanType() &&
+ Kind.getKind() == InitializationKind::IK_Direct) {
+ AddConversionSequenceStep(
+ ImplicitConversionSequence::getNullptrToBool(SourceType, DestType,
+ Initializer->isGLValue()),
+ DestType);
+ return;
+ }
+
// - Otherwise, the initial value of the object being initialized is the
// (possibly converted) value of the initializer expression. Standard
// conversions (Clause 4) will be used, if necessary, to convert the
@@ -5863,7 +5910,7 @@ void InitializationSequence::InitializeFrom(Sema &S,
ImplicitConversionSequence ICS
= S.TryImplicitConversion(Initializer, DestType,
/*SuppressUserConversions*/true,
- /*AllowExplicitConversions*/ false,
+ Sema::AllowedExplicit::None,
/*InOverloadResolution*/ false,
/*CStyle=*/Kind.isCStyleOrFunctionalCast(),
allowObjCWritebackConversion);
@@ -6416,12 +6463,14 @@ PerformConstructorInitialization(Sema &S,
}
S.MarkFunctionReferenced(Loc, Constructor);
- CurInit = CXXTemporaryObjectExpr::Create(
- S.Context, Constructor,
- Entity.getType().getNonLValueExprType(S.Context), TSInfo,
- ConstructorArgs, ParenOrBraceRange, HadMultipleCandidates,
- IsListInitialization, IsStdInitListInitialization,
- ConstructorInitRequiresZeroInit);
+ CurInit = S.CheckForImmediateInvocation(
+ CXXTemporaryObjectExpr::Create(
+ S.Context, Constructor,
+ Entity.getType().getNonLValueExprType(S.Context), TSInfo,
+ ConstructorArgs, ParenOrBraceRange, HadMultipleCandidates,
+ IsListInitialization, IsStdInitListInitialization,
+ ConstructorInitRequiresZeroInit),
+ Constructor);
} else {
CXXConstructExpr::ConstructionKind ConstructKind =
CXXConstructExpr::CK_Complete;
@@ -8159,9 +8208,13 @@ ExprResult InitializationSequence::Perform(Sema &S,
if (const auto *ToPtrType = Step->Type->getAs<PointerType>()) {
if (FromPtrType->getPointeeType()->hasAttr(attr::NoDeref) &&
!ToPtrType->getPointeeType()->hasAttr(attr::NoDeref)) {
- S.Diag(CurInit.get()->getExprLoc(),
- diag::warn_noderef_to_dereferenceable_pointer)
- << CurInit.get()->getSourceRange();
+ // Do not check static casts here because they are checked earlier
+ // in Sema::ActOnCXXNamedCast()
+ if (!Kind.isStaticCast()) {
+ S.Diag(CurInit.get()->getExprLoc(),
+ diag::warn_noderef_to_dereferenceable_pointer)
+ << CurInit.get()->getSourceRange();
+ }
}
}
}
@@ -8762,7 +8815,7 @@ bool InitializationSequence::Diagnose(Sema &S,
case FK_UTF8StringIntoPlainChar:
S.Diag(Kind.getLocation(),
diag::err_array_init_utf8_string_into_char)
- << S.getLangOpts().CPlusPlus2a;
+ << S.getLangOpts().CPlusPlus20;
break;
case FK_ArrayTypeMismatch:
case FK_NonConstantArrayInit:
@@ -8889,6 +8942,11 @@ bool InitializationSequence::Diagnose(Sema &S,
<< Args[0]->getSourceRange();
break;
+ case FK_NonConstLValueReferenceBindingToMatrixElement:
+ S.Diag(Kind.getLocation(), diag::err_reference_bind_to_matrix_element)
+ << DestType.isVolatileQualified() << Args[0]->getSourceRange();
+ break;
+
case FK_RValueReferenceBindingToLValue:
S.Diag(Kind.getLocation(), diag::err_lvalue_to_rvalue_ref)
<< DestType.getNonReferenceType() << OnlyArg->getType()
@@ -9234,6 +9292,10 @@ void InitializationSequence::dump(raw_ostream &OS) const {
OS << "non-const lvalue reference bound to vector element";
break;
+ case FK_NonConstLValueReferenceBindingToMatrixElement:
+ OS << "non-const lvalue reference bound to matrix element";
+ break;
+
case FK_NonConstLValueReferenceBindingToUnrelated:
OS << "non-const lvalue reference bound to unrelated type";
break;