summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaDeclCXX.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2019-09-18 17:37:44 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2019-09-18 17:37:44 +0000
commitc667cdc850c2aa821ffeedbc08c24bc985c59edd (patch)
treec0ee14f77a8bf3bcc8485bae5c413767ba09cd35 /clang/lib/Sema/SemaDeclCXX.cpp
parente406a3f2d64ca3a047d7289add5932bd41e881a4 (diff)
downloadbcm5719-llvm-c667cdc850c2aa821ffeedbc08c24bc985c59edd.tar.gz
bcm5719-llvm-c667cdc850c2aa821ffeedbc08c24bc985c59edd.zip
[c++20] P1331R2: Allow transient use of uninitialized objects in
constant evaluation. llvm-svn: 372237
Diffstat (limited to 'clang/lib/Sema/SemaDeclCXX.cpp')
-rw-r--r--clang/lib/Sema/SemaDeclCXX.cpp41
1 files changed, 30 insertions, 11 deletions
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 1bedecd7847..f7c2695d579 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -1778,7 +1778,8 @@ static bool CheckConstexprDeclStmt(Sema &SemaRef, const FunctionDecl *Dcl,
case Decl::Decomposition: {
// C++1y [dcl.constexpr]p3 allows anything except:
// a definition of a variable of non-literal type or of static or
- // thread storage duration or for which no initialization is performed.
+ // thread storage duration or [before C++2a] for which no
+ // initialization is performed.
const auto *VD = cast<VarDecl>(DclIt);
if (VD->isThisDeclarationADefinition()) {
if (VD->isStaticLocal()) {
@@ -1797,11 +1798,16 @@ static bool CheckConstexprDeclStmt(Sema &SemaRef, const FunctionDecl *Dcl,
if (!VD->getType()->isDependentType() &&
!VD->hasInit() && !VD->isCXXForRangeDecl()) {
if (Kind == Sema::CheckConstexprKind::Diagnose) {
- SemaRef.Diag(VD->getLocation(),
- diag::err_constexpr_local_var_no_init)
- << isa<CXXConstructorDecl>(Dcl);
+ SemaRef.Diag(
+ VD->getLocation(),
+ SemaRef.getLangOpts().CPlusPlus2a
+ ? diag::warn_cxx17_compat_constexpr_local_var_no_init
+ : diag::ext_constexpr_local_var_no_init)
+ << isa<CXXConstructorDecl>(Dcl);
+ } else if (!SemaRef.getLangOpts().CPlusPlus2a) {
+ return false;
}
- return false;
+ continue;
}
}
if (Kind == Sema::CheckConstexprKind::Diagnose) {
@@ -1855,6 +1861,11 @@ static bool CheckConstexprCtorInitializer(Sema &SemaRef,
llvm::SmallSet<Decl*, 16> &Inits,
bool &Diagnosed,
Sema::CheckConstexprKind Kind) {
+ // In C++20 onwards, there's nothing to check for validity.
+ if (Kind == Sema::CheckConstexprKind::CheckValid &&
+ SemaRef.getLangOpts().CPlusPlus2a)
+ return true;
+
if (Field->isInvalidDecl())
return true;
@@ -1873,12 +1884,15 @@ static bool CheckConstexprCtorInitializer(Sema &SemaRef,
if (!Inits.count(Field)) {
if (Kind == Sema::CheckConstexprKind::Diagnose) {
if (!Diagnosed) {
- SemaRef.Diag(Dcl->getLocation(), diag::err_constexpr_ctor_missing_init);
+ SemaRef.Diag(Dcl->getLocation(),
+ SemaRef.getLangOpts().CPlusPlus2a
+ ? diag::warn_cxx17_compat_constexpr_ctor_missing_init
+ : diag::ext_constexpr_ctor_missing_init);
Diagnosed = true;
}
SemaRef.Diag(Field->getLocation(),
diag::note_constexpr_ctor_missing_init);
- } else {
+ } else if (!SemaRef.getLangOpts().CPlusPlus2a) {
return false;
}
} else if (Field->isAnonymousStructOrUnion()) {
@@ -2121,10 +2135,15 @@ static bool CheckConstexprFunctionBody(Sema &SemaRef, const FunctionDecl *Dcl,
if (RD->isUnion()) {
if (Constructor->getNumCtorInitializers() == 0 &&
RD->hasVariantMembers()) {
- if (Kind == Sema::CheckConstexprKind::Diagnose)
- SemaRef.Diag(Dcl->getLocation(),
- diag::err_constexpr_union_ctor_no_init);
- return false;
+ if (Kind == Sema::CheckConstexprKind::Diagnose) {
+ SemaRef.Diag(
+ Dcl->getLocation(),
+ SemaRef.getLangOpts().CPlusPlus2a
+ ? diag::warn_cxx17_compat_constexpr_union_ctor_no_init
+ : diag::ext_constexpr_union_ctor_no_init);
+ } else if (!SemaRef.getLangOpts().CPlusPlus2a) {
+ return false;
+ }
}
} else if (!Constructor->isDependentContext() &&
!Constructor->isDelegatingConstructor()) {
OpenPOWER on IntegriCloud