Skip to content

Conversation

cor3ntin
Copy link
Contributor

The conditions of a noexcept and explicit specifier are full expressions. Before this patch, we would call ActOnFinishFullExpr on these in the context of the enclosing expression, which would cause the collect of odr-used variables (and subsequently capture attempts) in the wrong (enclosing) context.

This was observable when parsing the noexcept specifier condition of a lambda appearing in a wider full expression odr-using variables.

Fixes #67492

The conditions of a noexcept and explicit specifier are full expressions.
Before this patch, we would call ActOnFinishFullExpr on these in the context
of the enclosing expression, which would cause the collect of odr-used variables
(and subsequently capture attempts) in the wrong (enclosing) context.

This was observable when parsing the noexcept specifier condition of a
lambda appearing in a wider full expression odr-using variables.

Fixes llvm#67492
@cor3ntin cor3ntin added clang:frontend Language frontend issues, e.g. anything involving "Sema" rejects-valid labels Sep 27, 2023
@llvmbot llvmbot added the clang Clang issues not falling into any other category label Sep 27, 2023
@llvmbot
Copy link
Member

llvmbot commented Sep 27, 2023

@llvm/pr-subscribers-clang

Changes

The conditions of a noexcept and explicit specifier are full expressions. Before this patch, we would call ActOnFinishFullExpr on these in the context of the enclosing expression, which would cause the collect of odr-used variables (and subsequently capture attempts) in the wrong (enclosing) context.

This was observable when parsing the noexcept specifier condition of a lambda appearing in a wider full expression odr-using variables.

Fixes #67492


Full diff: https://github.com/llvm/llvm-project/pull/67538.diff

4 Files Affected:

  • (modified) clang/docs/ReleaseNotes.rst (+4)
  • (modified) clang/lib/Parse/ParseDecl.cpp (+5-1)
  • (modified) clang/lib/Parse/ParseDeclCXX.cpp (+5-1)
  • (modified) clang/test/SemaCXX/lambda-expressions.cpp (+5)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index a17efab57bcdfa3..d74cd46c3bfccc6 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -363,6 +363,10 @@ Bug Fixes to C++ Support
   reference. Fixes:
   (`#64162 <https://github.com/llvm/llvm-project/issues/64162>`_)
 
+- Clang no longer tries to capture non-odr-used variables that appear
+  in the enclosing expression of a lambda expression with a noexcept specifier.
+  (`#67492 <https://github.com/llvm/llvm-project/issues/67492>`_)
+
 Bug Fixes to AST Handling
 ^^^^^^^^^^^^^^^^^^^^^^^^^
 - Fixed an import failure of recursive friend class template.
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index f5b4107cc32c1f0..735d7a861c7bead 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -4162,7 +4162,11 @@ void Parser::ParseDeclarationSpecifiers(
           ExprResult ExplicitExpr(static_cast<Expr *>(nullptr));
           BalancedDelimiterTracker Tracker(*this, tok::l_paren);
           Tracker.consumeOpen();
-          ExplicitExpr = ParseConstantExpression();
+
+          EnterExpressionEvaluationContext ConstantEvaluated(
+              Actions, Sema::ExpressionEvaluationContext::ConstantEvaluated);
+
+          ExplicitExpr = ParseConstantExpressionInExprEvalContext();
           ConsumedEnd = Tok.getLocation();
           if (ExplicitExpr.isUsable()) {
             CloseParenLoc = Tok.getLocation();
diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp
index e5a278c598cfb63..6cae537ed21e215 100644
--- a/clang/lib/Parse/ParseDeclCXX.cpp
+++ b/clang/lib/Parse/ParseDeclCXX.cpp
@@ -3988,7 +3988,11 @@ ExceptionSpecificationType Parser::tryParseExceptionSpecification(
     // There is an argument.
     BalancedDelimiterTracker T(*this, tok::l_paren);
     T.consumeOpen();
-    NoexceptExpr = ParseConstantExpression();
+
+    EnterExpressionEvaluationContext ConstantEvaluated(
+        Actions, Sema::ExpressionEvaluationContext::ConstantEvaluated);
+    NoexceptExpr = ParseConstantExpressionInExprEvalContext();
+
     T.consumeClose();
     if (!NoexceptExpr.isInvalid()) {
       NoexceptExpr =
diff --git a/clang/test/SemaCXX/lambda-expressions.cpp b/clang/test/SemaCXX/lambda-expressions.cpp
index 0c9e8584e653473..9cf81a0a195a573 100644
--- a/clang/test/SemaCXX/lambda-expressions.cpp
+++ b/clang/test/SemaCXX/lambda-expressions.cpp
@@ -718,3 +718,8 @@ void foo() {
 void GH48527() {
   auto a = []()__attribute__((b(({ return 0; })))){}; // expected-warning {{unknown attribute 'b' ignored}}
 }
+
+void GH67492() {
+  constexpr auto test = 42;
+  auto lambda = (test, []() noexcept(true) {});
+}

@shafik
Copy link
Collaborator

shafik commented Sep 27, 2023

I wonder does this also fix this: #67058

@cor3ntin
Copy link
Contributor Author

I wonder does this also fix this: #67058

Nope, this is unrelated, sadly.

@cor3ntin cor3ntin merged commit 64ffe64 into llvm:main Sep 28, 2023
@cor3ntin cor3ntin deleted the corentin/gh67492 branch September 28, 2023 15:22
legrosbuffle pushed a commit to legrosbuffle/llvm-project that referenced this pull request Sep 29, 2023
llvm#67538)

The conditions of a noexcept and explicit specifier are full
expressions. Before this patch, we would call ActOnFinishFullExpr on
these in the context of the enclosing expression, which would cause the
collect of odr-used variables (and subsequently capture attempts) in the
wrong (enclosing) context.

This was observable when parsing the noexcept specifier condition of a
lambda appearing in a wider full expression odr-using variables.

Fixes llvm#67492
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category rejects-valid
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Clang 17 regression: variable 'test' cannot be implicitly captured variable is not referenced in lambda
4 participants