diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp --- a/clang/lib/Parse/Parser.cpp +++ b/clang/lib/Parse/Parser.cpp @@ -14,6 +14,7 @@ #include "clang/AST/ASTConsumer.h" #include "clang/AST/ASTContext.h" #include "clang/AST/DeclTemplate.h" +#include "clang/AST/ASTLambda.h" #include "clang/Basic/FileManager.h" #include "clang/Parse/ParseDiagnostic.h" #include "clang/Parse/RAIIObjectsForParser.h" @@ -1404,6 +1405,17 @@ if (BodyKind == Sema::FnBodyKind::Other) SkipFunctionBody(); + // ExpressionEvaluationContext is pushed in ActOnStartOfFunctionDef + // and it would be popped in ActOnFinishFunctionBody. + // We pop it explcitly here since ActOnFinishFunctionBody won't get called. + // + // Do not call PopExpressionEvaluationContext() if it is a lambda because + // one is already popped when finishing the lambda in BuildLambdaExpr(). + // + // FIXME: It looks not easy to balance PushExpressionEvaluationContext() + // and PopExpressionEvaluationContext(). + if (!isLambdaCallOperator(dyn_cast_if_present(Res))) + Actions.PopExpressionEvaluationContext(); return Res; } diff --git a/clang/test/Modules/pr60275.cppm b/clang/test/Modules/pr60275.cppm new file mode 100644 --- /dev/null +++ b/clang/test/Modules/pr60275.cppm @@ -0,0 +1,40 @@ +// Address: https://github.com/llvm/llvm-project/issues/60275 +// +// RUN: rm -rf %t +// RUN: mkdir -p %t +// RUN: split-file %s %t +// +// RUN: %clang_cc1 -std=c++20 -triple %itanium_abi_triple -emit-module-interface %t/a.cppm -o %t/a.pcm +// RUN: %clang_cc1 -std=c++20 -triple %itanium_abi_triple %t/b.cpp -fmodule-file=%t/a.pcm -emit-llvm -o - | FileCheck %t/b.cpp +//--- foo.h + +consteval void global() {} + +//--- a.cppm +module; +#include "foo.h" +export module a; + +//--- b.cpp +#include "foo.h" +import a; + +consteval int b() { + return 0; +} + +struct bb { + int m = b(); +}; + +void bbb() { + bb x; +} + +// CHECK: define{{.*}}_ZN2bbC2Ev({{.*}}[[THIS:%.+]]) +// CHECK-NEXT: entry: +// CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca ptr +// CHECK-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]] +// CHECK-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]] +// CHECK-NEXT: [[M_ADDR:%.*]] = getelementptr{{.*}}%struct.bb, ptr [[THIS1]], i32 0, i32 0 +// CHECK-NEXT: store i32 0, ptr [[M_ADDR]]