cor3ntin updated this revision to Diff 417586. cor3ntin added a comment. - Fix test - Add a comment explaining why we do not use CheckLiteralType
@aaron,ballman I completely missed that...! However, CheckLiteralType does a bunch of tests that we do not need to diagnose *why* a type is not literal, which we do not care about here. I tried to play around with the code and trying to use CheckLiteralType, or to modify it for this scenario does not appear to me an improvenent, so I rather keep the change as is. I also fixed the fail test, i think i accidentally removed a line from the test file... Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D122249/new/ https://reviews.llvm.org/D122249 Files: clang/include/clang/Basic/DiagnosticSemaKinds.td clang/lib/Sema/SemaDeclCXX.cpp clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3-2b.cpp clang/test/SemaCXX/constant-expression-cxx2b.cpp
Index: clang/test/SemaCXX/constant-expression-cxx2b.cpp =================================================================== --- clang/test/SemaCXX/constant-expression-cxx2b.cpp +++ clang/test/SemaCXX/constant-expression-cxx2b.cpp @@ -96,7 +96,7 @@ constexpr int non_literal(bool b) { if (!b) return 0; - NonLiteral n; + NonLiteral n; // cxx2b-warning {{definition of a variable of non-literal type in a constexpr function is incompatible with C++ standards before C++2b}} } constexpr int non_literal_1 = non_literal(false); @@ -164,7 +164,8 @@ auto non_literal = [](bool b) constexpr { if (!b) NonLiteral n; // cxx2b-note {{non-literal type 'NonLiteral' cannot be used in a constant expression}} \ - // cxx2a-error {{variable of non-literal type 'NonLiteral' cannot be defined in a constexpr function before C++2b}} + // cxx2a-error {{variable of non-literal type 'NonLiteral' cannot be defined in a constexpr function before C++2b}} \ + // cxx2b-warning {{definition of a variable of non-literal type in a constexpr function is incompatible with C++ standards before C++2b}} return 0; }; @@ -227,7 +228,7 @@ } template <typename T> -constexpr auto dependent_var_def_lambda(void) { +constexpr auto dependent_var_def_lambda() { return [](bool b) { // cxx2a-note {{declared here}} if (!b) T t; @@ -237,4 +238,4 @@ constexpr auto non_literal_valid_in_cxx2b = dependent_var_def_lambda<NonLiteral>()(true); // \ // cxx2a-error {{constexpr variable 'non_literal_valid_in_cxx2b' must be initialized by a constant expression}} \ - // cxx2a-note {{non-constexpr function}} + // cxx2a-note {{non-constexpr function}} Index: clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3-2b.cpp =================================================================== --- clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3-2b.cpp +++ clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3-2b.cpp @@ -30,12 +30,13 @@ }; constexpr void non_literal() { // expected-error {{constexpr function never produces a constant expression}} - NonLiteral n; // expected-note {{non-literal type 'NonLiteral' cannot be used in a constant expression}} + NonLiteral n; // expected-note {{non-literal type 'NonLiteral' cannot be used in a constant expression}} \ + // expected-warning {{definition of a variable of non-literal type in a constexpr function is incompatible with C++ standards before C++2b}} } constexpr void non_literal2(bool b) { if (!b) - NonLiteral n; + NonLiteral n; // expected-warning {{definition of a variable of non-literal type in a constexpr function is incompatible with C++ standards before C++2b}} } constexpr int c_thread_local(int n) { Index: clang/lib/Sema/SemaDeclCXX.cpp =================================================================== --- clang/lib/Sema/SemaDeclCXX.cpp +++ clang/lib/Sema/SemaDeclCXX.cpp @@ -1893,7 +1893,7 @@ if (Kind == Sema::CheckConstexprKind::Diagnose) { SemaRef.Diag(VD->getLocation(), SemaRef.getLangOpts().CPlusPlus2b - ? diag::warn_cxx20_compat_constexpr_static_var + ? diag::warn_cxx20_compat_constexpr_var : diag::ext_constexpr_static_var) << isa<CXXConstructorDecl>(Dcl) << (VD->getTLSKind() == VarDecl::TLS_Dynamic); @@ -1901,10 +1901,19 @@ return false; } } - if (!SemaRef.LangOpts.CPlusPlus2b && - CheckLiteralType(SemaRef, Kind, VD->getLocation(), VD->getType(), - diag::err_constexpr_local_var_non_literal_type, - isa<CXXConstructorDecl>(Dcl))) + if (SemaRef.LangOpts.CPlusPlus2b) { + // We do not use CheckLiteralType here because we want to + // emit a warning but no notes explaining why the type is not literal. + if (Kind == Sema::CheckConstexprKind::Diagnose && + !VD->getType()->isDependentType() && + !VD->getType()->isLiteralType(SemaRef.Context)) + SemaRef.Diag(VD->getLocation(), + diag::warn_cxx20_compat_constexpr_var) + << isa<CXXConstructorDecl>(Dcl) << 2; + } else if (CheckLiteralType( + SemaRef, Kind, VD->getLocation(), VD->getType(), + diag::err_constexpr_local_var_non_literal_type, + isa<CXXConstructorDecl>(Dcl))) return false; if (!VD->getType()->isDependentType() && !VD->hasInit() && !VD->isCXXForRangeDecl()) { Index: clang/include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- clang/include/clang/Basic/DiagnosticSemaKinds.td +++ clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -2721,9 +2721,9 @@ "definition of a %select{static|thread_local}1 variable " "in a constexpr %select{function|constructor}0 " "is a C++2b extension">, InGroup<CXX2b>; -def warn_cxx20_compat_constexpr_static_var : Warning< - "definition of a %select{static|thread_local}1 variable " - "in a constexpr %select{function|constructor}0 " +def warn_cxx20_compat_constexpr_var : Warning< + "definition of a %select{static variable|thread_local variable|variable " + "of non-literal type}1 in a constexpr %select{function|constructor}0 " "is incompatible with C++ standards before C++2b">, InGroup<CXXPre2bCompat>, DefaultIgnore; def err_constexpr_local_var_non_literal_type : Error<
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits