llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Shafik Yaghmour (shafik) <details> <summary>Changes</summary> When this diagnostic was implemented it fired for all non-static data members. I added checking so that it only fires for constructors and destructors before C++26 (which now allows this). Some special care was required for the destructor case since constexpr constuctors were not allowed in C++11. Modified existing test to cover the new conditions. Also filed bug report on bad diagnostic found while writing the tests: https://github.com/llvm/llvm-project/issues/163683 Fixes: https://github.com/llvm/llvm-project/issues/97266 --- Full diff: https://github.com/llvm/llvm-project/pull/163690.diff 3 Files Affected: - (modified) clang/include/clang/Basic/DiagnosticSemaKinds.td (+1-1) - (modified) clang/lib/Sema/SemaDeclCXX.cpp (+6-4) - (modified) clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp (+8-2) ``````````diff diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 40bc7b9a4e45e..0eae2b76ff9b9 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -3026,7 +3026,7 @@ def warn_cxx17_compat_constexpr_virtual : Warning< "virtual constexpr functions are incompatible with " "C++ standards before C++20">, InGroup<CXXPre20Compat>, DefaultIgnore; def err_constexpr_virtual_base : Error< - "constexpr %select{member function|constructor}0 not allowed in " + "constexpr %select{destructor|constructor}0 not allowed in " "%select{struct|interface|class}1 with virtual base " "%plural{1:class|:classes}2">; def note_non_literal_incomplete : Note< diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index d41ab126c426f..da94b0070dfcb 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -1918,8 +1918,10 @@ static bool CheckConstexprMissingReturn(Sema &SemaRef, const FunctionDecl *Dcl); bool Sema::CheckConstexprFunctionDefinition(const FunctionDecl *NewFD, CheckConstexprKind Kind) { - const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(NewFD); - if (MD && MD->isInstance()) { + if ((!getLangOpts().CPlusPlus26 && isa<CXXConstructorDecl>(NewFD)) || + ((getLangOpts().CPlusPlus20 && !getLangOpts().CPlusPlus26) && + isa<CXXDestructorDecl>(NewFD))) { + const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(NewFD); // C++11 [dcl.constexpr]p4: // The definition of a constexpr constructor shall satisfy the following // constraints: @@ -1933,8 +1935,8 @@ bool Sema::CheckConstexprFunctionDefinition(const FunctionDecl *NewFD, return false; Diag(NewFD->getLocation(), diag::err_constexpr_virtual_base) - << isa<CXXConstructorDecl>(NewFD) - << getRecordDiagFromTagKind(RD->getTagKind()) << RD->getNumVBases(); + << isa<CXXConstructorDecl>(NewFD) + << getRecordDiagFromTagKind(RD->getTagKind()) << RD->getNumVBases(); for (const auto &I : RD->vbases()) Diag(I.getBeginLoc(), diag::note_constexpr_virtual_base_here) << I.getSourceRange(); diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp index 51990ee4341d2..5a06d686b4c0f 100644 --- a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp +++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp @@ -84,10 +84,16 @@ struct T3 { struct U { constexpr U SelfReturn() const; constexpr int SelfParam(U) const; + constexpr ~U(); // beforecxx20-error {{destructor cannot be declared constexpr}} }; -struct V : virtual U { // expected-note {{here}} - constexpr int F() const { return 0; } // expected-error {{constexpr member function not allowed in struct with virtual base class}} +struct V : virtual U { // expected-note {{here}} //aftercxx20-note {{here}} + constexpr V() {} // expected-error {{constexpr constructor not allowed in struct with virtual base class}} + constexpr ~V() {} // aftercxx20-error {{constexpr destructor not allowed in struct with virtual base class}} + // beforecxx20-error@-1 {{destructor cannot be declared constexpr}} + // beforecxx14-error@-2 {{constexpr function's return type 'void' is not a literal type}} + // ^ FIXME this is just a bad diagnostic + constexpr int f() const { return 0; } }; // or a compound-statememt that contains only [CXX11] `````````` </details> https://github.com/llvm/llvm-project/pull/163690 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
