r332286 - PR37450: Fix bug that disabled some type checks for variables with deduced types.
Richard Smith via cfe-commits
cfe-commits at lists.llvm.org
Mon May 14 13:15:04 PDT 2018
Author: rsmith
Date: Mon May 14 13:15:04 2018
New Revision: 332286
URL: http://llvm.org/viewvc/llvm-project?rev=332286&view=rev
Log:
PR37450: Fix bug that disabled some type checks for variables with deduced types.
Also improve diagnostic for the case where a type is non-literal because it's a lambda.
Modified:
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/lib/Sema/SemaType.cpp
cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p3.cpp
cfe/trunk/test/SemaCXX/cxx1z-constexpr-lambdas.cpp
cfe/trunk/test/SemaCXX/for-range-examples.cpp
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=332286&r1=332285&r2=332286&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Mon May 14 13:15:04 2018
@@ -2381,6 +2381,8 @@ def note_non_literal_user_provided_dtor
"%0 is not literal because it has a user-provided destructor">;
def note_non_literal_nontrivial_dtor : Note<
"%0 is not literal because it has a non-trivial destructor">;
+def note_non_literal_lambda : Note<
+ "lambda closure types are non-literal types before C++17">;
def warn_private_extern : Warning<
"use of __private_extern__ on a declaration may not produce external symbol "
"private to the linkage unit and is deprecated">, InGroup<PrivateExtern>;
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=332286&r1=332285&r2=332286&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Mon May 14 13:15:04 2018
@@ -7293,8 +7293,7 @@ void Sema::CheckVariableDeclarationType(
if (NewVD->isInvalidDecl())
return;
- TypeSourceInfo *TInfo = NewVD->getTypeSourceInfo();
- QualType T = TInfo->getType();
+ QualType T = NewVD->getType();
// Defer checking an 'auto' type until its initializer is attached.
if (T->isUndeducedType())
@@ -7438,10 +7437,18 @@ void Sema::CheckVariableDeclarationType(
(T->isVariableArrayType() && NewVD->hasGlobalStorage())) {
bool SizeIsNegative;
llvm::APSInt Oversized;
- TypeSourceInfo *FixedTInfo =
- TryToFixInvalidVariablyModifiedTypeSourceInfo(TInfo, Context,
- SizeIsNegative, Oversized);
- if (!FixedTInfo && T->isVariableArrayType()) {
+ TypeSourceInfo *FixedTInfo = TryToFixInvalidVariablyModifiedTypeSourceInfo(
+ NewVD->getTypeSourceInfo(), Context, SizeIsNegative, Oversized);
+ QualType FixedT;
+ if (FixedTInfo && T == NewVD->getTypeSourceInfo()->getType())
+ FixedT = FixedTInfo->getType();
+ else if (FixedTInfo) {
+ // Type and type-as-written are canonically different. We need to fix up
+ // both types separately.
+ FixedT = TryToFixInvalidVariablyModifiedType(T, Context, SizeIsNegative,
+ Oversized);
+ }
+ if ((!FixedTInfo || FixedT.isNull()) && T->isVariableArrayType()) {
const VariableArrayType *VAT = Context.getAsVariableArrayType(T);
// FIXME: This won't give the correct result for
// int a[10][n];
@@ -7470,7 +7477,7 @@ void Sema::CheckVariableDeclarationType(
}
Diag(NewVD->getLocation(), diag::warn_illegal_constant_array_size);
- NewVD->setType(FixedTInfo->getType());
+ NewVD->setType(FixedT);
NewVD->setTypeSourceInfo(FixedTInfo);
}
Modified: cfe/trunk/lib/Sema/SemaType.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=332286&r1=332285&r2=332286&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaType.cpp (original)
+++ cfe/trunk/lib/Sema/SemaType.cpp Mon May 14 13:15:04 2018
@@ -7809,6 +7809,13 @@ bool Sema::RequireLiteralType(SourceLoca
if (RequireCompleteType(Loc, ElemType, diag::note_non_literal_incomplete, T))
return true;
+ // [expr.prim.lambda]p3:
+ // This class type is [not] a literal type.
+ if (RD->isLambda() && !getLangOpts().CPlusPlus17) {
+ Diag(RD->getLocation(), diag::note_non_literal_lambda);
+ return true;
+ }
+
// If the class has virtual base classes, then it's not an aggregate, and
// cannot have any constexpr constructors or a trivial default constructor,
// so is non-literal. This is better to diagnose than the resulting absence
Modified: cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p3.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p3.cpp?rev=332286&r1=332285&r2=332286&view=diff
==============================================================================
--- cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p3.cpp (original)
+++ cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p3.cpp Mon May 14 13:15:04 2018
@@ -1,11 +1,19 @@
// RUN: %clang_cc1 -fsyntax-only -std=c++11 %s -verify
+// RUN: %clang_cc1 -fsyntax-only -std=c++14 %s -verify
+// RUN: %clang_cc1 -fsyntax-only -std=c++17 %s -verify
void test_nonaggregate(int i) {
auto lambda = [i]() -> void {}; // expected-note 2{{candidate constructor}}
decltype(lambda) foo = { 1 }; // expected-error{{no matching constructor}}
- static_assert(!__is_literal(decltype(lambda)), "");
+ static_assert(__is_literal(decltype(lambda)) == (__cplusplus >= 201703L), "");
auto lambda2 = []{}; // expected-note 2{{candidate constructor}}
decltype(lambda2) bar = {}; // expected-error{{no matching constructor}}
- static_assert(!__is_literal(decltype(lambda2)), "");
+ static_assert(__is_literal(decltype(lambda2)) == (__cplusplus >= 201703L), "");
}
+
+constexpr auto literal = []{};
+#if __cplusplus < 201703L
+// expected-error at -2 {{constexpr variable cannot have non-literal type}}
+// expected-note at -3 {{lambda closure types are non-literal types before C++17}}
+#endif
Modified: cfe/trunk/test/SemaCXX/cxx1z-constexpr-lambdas.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx1z-constexpr-lambdas.cpp?rev=332286&r1=332285&r2=332286&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/cxx1z-constexpr-lambdas.cpp (original)
+++ cfe/trunk/test/SemaCXX/cxx1z-constexpr-lambdas.cpp Mon May 14 13:15:04 2018
@@ -6,7 +6,7 @@
namespace test_lambda_is_literal {
#ifdef CPP14_AND_EARLIER
//expected-error at +4{{not a literal type}}
-//expected-note at +2{{not an aggregate and has no constexpr constructors}}
+//expected-note at +2{{lambda closure types are non-literal types before C++17}}
#endif
auto L = [] { };
constexpr int foo(decltype(L) l) { return 0; }
Modified: cfe/trunk/test/SemaCXX/for-range-examples.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/for-range-examples.cpp?rev=332286&r1=332285&r2=332286&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/for-range-examples.cpp (original)
+++ cfe/trunk/test/SemaCXX/for-range-examples.cpp Mon May 14 13:15:04 2018
@@ -221,11 +221,7 @@ namespace test7 {
for (c alignas(8) : arr) { // expected-error {{requires type for loop variable}}
static_assert(alignof(c) == 8, ""); // expected-warning {{extension}}
}
- // FIXME: The fix-it hint here is not sufficient to fix the error.
- // We fail to diagnose that d is underaligned for its type, because
- // we check the alignment attribute before we perform the auto
- // deduction.
- for (d alignas(1) : arr) {} // expected-error {{requires type for loop variable}}
+ for (d alignas(1) : arr) {} // expected-error {{requested alignment is less than minimum alignment of 8 for type 'int &'}} expected-error {{requires type for loop variable}}
for (e [[deprecated]] : arr) { e = 0; } // expected-warning {{deprecated}} expected-note {{here}} expected-error {{requires type for loop variable}}
}
}
@@ -274,4 +270,4 @@ int foo(int b) {
}();
return b;
}
-}
\ No newline at end of file
+}
More information about the cfe-commits
mailing list