Author: Mariya Podchishchaeva Date: 2023-03-06T03:38:49-05:00 New Revision: 2fbf18b40026b46bd380fae58575cebbd9801ff4
URL: https://github.com/llvm/llvm-project/commit/2fbf18b40026b46bd380fae58575cebbd9801ff4 DIFF: https://github.com/llvm/llvm-project/commit/2fbf18b40026b46bd380fae58575cebbd9801ff4.diff LOG: [clang] Fix aggregate initialization inside lambda constexpr Constant evaluator only considered access to `this` pointer to be possible if `this` poitners was captured. However `this` can also appear if there was a default member initializer. Fixes https://github.com/llvm/llvm-project/issues/60936 Reviewed By: shafik Differential Revision: https://reviews.llvm.org/D144866 Added: Modified: clang/docs/ReleaseNotes.rst clang/lib/AST/ExprConstant.cpp clang/test/SemaCXX/lambda-expressions.cpp Removed: ################################################################################ diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 988bcf1860987..cd91fbe78bb2b 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -178,6 +178,8 @@ Bug Fixes in This Version (`#57682 <https://github.com/llvm/llvm-project/issues/57682>`_) - Clang now support export declarations in the language linkage. (`#60405 <https://github.com/llvm/llvm-project/issues/60405>`_) +- Fix aggregate initialization inside lambda constexpr. + (`#60936 <https://github.com/llvm/llvm-project/issues/60936>`_) Bug Fixes to Compiler Builtins ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 9e67f862ae634..6b0beb1973893 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -8758,16 +8758,19 @@ class PointerExprEvaluator return false; } Result = *Info.CurrentCall->This; - // If we are inside a lambda's call operator, the 'this' expression refers - // to the enclosing '*this' object (either by value or reference) which is - // either copied into the closure object's field that represents the '*this' - // or refers to '*this'. + if (isLambdaCallOperator(Info.CurrentCall->Callee)) { - // Ensure we actually have captured 'this'. (an error will have - // been previously reported if not). + // Ensure we actually have captured 'this'. If something was wrong with + // 'this' capture, the error would have been previously reported. + // Otherwise we can be inside of a default initialization of an object + // declared by lambda's body, so no need to return false. if (!Info.CurrentCall->LambdaThisCaptureField) - return false; + return true; + // If we have captured 'this', the 'this' expression refers + // to the enclosing '*this' object (either by value or reference) which is + // either copied into the closure object's field that represents the + // '*this' or refers to '*this'. // Update 'Result' to refer to the data member/field of the closure object // that represents the '*this' capture. if (!HandleLValueMember(Info, E, Result, diff --git a/clang/test/SemaCXX/lambda-expressions.cpp b/clang/test/SemaCXX/lambda-expressions.cpp index 0c19d94e8bd9f..84d224fdc835e 100644 --- a/clang/test/SemaCXX/lambda-expressions.cpp +++ b/clang/test/SemaCXX/lambda-expressions.cpp @@ -689,3 +689,18 @@ void Func1() { } } + +#if __cplusplus > 201402L +namespace GH60936 { +struct S { + int i; + // `&i` in default initializer causes implicit `this` access. + int *p = &i; +}; + +static_assert([]() constexpr { + S r = S{2}; + return r.p != nullptr; +}()); +} // namespace GH60936 +#endif _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits