llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: llvmbot <details> <summary>Changes</summary> Backport 0d93f2aec0b4847761bd8458b7847ce37b85cf03 Requested by: @<!-- -->erichkeane --- Full diff: https://github.com/llvm/llvm-project/pull/209773.diff 3 Files Affected: - (modified) clang/lib/AST/ExprConstant.cpp (+11-2) - (modified) clang/lib/Sema/SemaExprCXX.cpp (+8) - (modified) clang/test/SemaCXX/enable_if.cpp (+39) ``````````diff diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 7d9dba8cd33fc..120af89a93b09 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -3212,8 +3212,17 @@ static bool HandleLValueMember(EvalInfo &Info, const Expr *E, LValue &LVal, const FieldDecl *FD, const ASTRecordLayout *RL = nullptr) { if (!RL) { - if (FD->getParent()->isInvalidDecl()) return false; - RL = &Info.Ctx.getASTRecordLayout(FD->getParent()); + const RecordDecl *RD = FD->getParent(); + if (RD->isInvalidDecl()) + return false; + // There are some cases where the base is not yet complete but we haven't + // disagnosed (such as in a template instantation of an attribute that + // references the expression, ala enable_if). These aren't necessarily + // constant expressions so we return 'false', but they might be, so we don't + // diagnose. + if (!RD->isCompleteDefinition()) + return false; + RL = &Info.Ctx.getASTRecordLayout(RD); } unsigned I = FD->getFieldIndex(); diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 5f22cd409dc01..538604aa2e64b 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -1487,6 +1487,14 @@ void Sema::MarkThisReferenced(CXXThisExpr *This) { } bool Sema::isThisOutsideMemberFunctionBody(QualType BaseType) { + // If we're outside the body of a member function, then we'll have a specified + // type for 'this'. Constraint substitution is the exception: a concept is + // evaluated in its own declaration context (see GH#197215), so it loses the + // enclosing '*this' even though it may legitimately name a member of the + // class currently being instantiated. + if (CXXThisTypeOverride.isNull() && !inConstraintSubstitution()) + return false; + // Determine whether we're looking into a class that's currently being // defined. CXXRecordDecl *Class = BaseType->getAsCXXRecordDecl(); diff --git a/clang/test/SemaCXX/enable_if.cpp b/clang/test/SemaCXX/enable_if.cpp index a34b87064b49d..4af0922fee5ac 100644 --- a/clang/test/SemaCXX/enable_if.cpp +++ b/clang/test/SemaCXX/enable_if.cpp @@ -646,6 +646,45 @@ void Substitute(Arg) __attribute__((enable_if(PlaceholderBitmask, ""))) { } +namespace GH199527 { +struct S { // expected-note {{definition of 'GH199527::S' is not complete until the closing '}'}} + ~S() {} + bool b; + // expected-error@+1{{member access into incomplete type 'S'}} + void foo(S b) __attribute__((enable_if(b.b, ""))); +}; + +template<typename T> +struct S2 { + bool b; + void foo(S2 b) const __attribute__((enable_if(b.b, "templ_foo_disabled"))); // #FOO +}; + +void use() { + S2<int> s_whatever; + S2<int> s_true{true}; + S2<int> s_false{false}; + + + // Both fail because this isn't a constexpr. + // expected-error@+2{{no matching member function for call to 'foo'}} + // expected-note@#FOO{{candidate disabled: templ_foo_disabled}} + s_whatever.foo(s_true); + // expected-error@+2{{no matching member function for call to 'foo'}} + // expected-note@#FOO{{candidate disabled: templ_foo_disabled}} + s_whatever.foo(s_false); + + constexpr S2<int> ce_s_whatever{}; + constexpr S2<int> ce_s_true{true}; + constexpr S2<int> ce_s_false{false}; + + ce_s_whatever.foo(ce_s_true); + // expected-error@+2{{no matching member function for call to 'foo'}} + // expected-note@#FOO{{candidate disabled: templ_foo_disabled}} + ce_s_whatever.foo(ce_s_false); +} +} + namespace DefaultArgs { void f(int n = __builtin_LINE()) __attribute__((enable_if(n == 12345, "only callable on line 12345"))); // expected-note {{only callable on line 12345}} void g() { f(); } // expected-error {{no matching function}} `````````` </details> https://github.com/llvm/llvm-project/pull/209773 _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
