llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
28.05k stars 11.58k forks source link

[C11] Properly handle materializing temporaries #96486

Open AaronBallman opened 2 months ago

AaronBallman commented 2 months ago

While investigating whether Clang properly implements WG14 N1285 (the factored approach), I found that Clang does not correctly materialize a temporary for the code that changed behavior:

struct X { int a[5]; } f();
int *p = f().a;
printf("%p\n", p);

https://godbolt.org/z/6q6bsabsj

In C11, that is an invalid use of a materialized temporary; in C99 it was required to work. Clang does not attempt to form a materialized temporary because of the language version check in: https://github.com/llvm/llvm-project/blob/c1bde0a2cb640b3607e9568b9a57b292e1f82666/clang/lib/Sema/SemaInit.cpp#L8667

Changing this to also materialize the temporary in C11 and later causes failed assertions in CodeGen:

# RUN: at line 1
f:\source\llvm-project\llvm\out\build\x64-debug\bin\clang.exe -cc1 -internal-isystem F:\source\llvm-project\llvm\out\build\x64-Debug\lib\clang\19\include -nostdsysteminc -triple aarch64_be-linux-gnu -ffreestanding -emit-llvm -O0 -o - F:\source\llvm-project\clang\test\CodeGen\arm64-be-hfa-vararg.c | f:\source\llvm-project\llvm\out\build\x64-debug\bin\filecheck.exe F:\source\llvm-project\clang\test\CodeGen\arm64-be-hfa-vararg.c
# executed command: 'f:\source\llvm-project\llvm\out\build\x64-debug\bin\clang.exe' -cc1 -internal-isystem 'F:\source\llvm-project\llvm\out\build\x64-Debug\lib\clang\19\include' -nostdsysteminc -triple aarch64_be-linux-gnu -ffreestanding -emit-llvm -O0 -o - 'F:\source\llvm-project\clang\test\CodeGen\arm64-be-hfa-vararg.c'
# .---command stderr------------
# | Assertion failed: isa<To>(Val) && "cast<Ty>() argument of incompatible type!", file F:\source\llvm-project\llvm\include\llvm/Support/Casting.h, line 578
# | PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace, preprocessed source, and associated run script.
# | Stack dump:
# | 0.  Program arguments: f:\\source\\llvm-project\\llvm\\out\\build\\x64-debug\\bin\\clang.exe -cc1 -internal-isystem F:\\source\\llvm-project\\llvm\\out\\build\\x64-Debug\\lib\\clang\\19\\include -nostdsysteminc -triple aarch64_be-linux-gnu -ffreestanding -emit-llvm -O0 -o - F:\\source\\llvm-project\\clang\\test\\CodeGen\\arm64-be-hfa-vararg.c
# | 1.  <eof> parser at end of file
# | 2.  F:\source\llvm-project\clang\test\CodeGen\arm64-be-hfa-vararg.c:6:8: LLVM IR generation of declaration 'callee'
# | 3.  F:\source\llvm-project\clang\test\CodeGen\arm64-be-hfa-vararg.c:6:8: Generating code for declaration 'callee'
# | Exception Code: 0x80000003
# |  #0 0x00007ff7124ddebc HandleAbort F:\source\llvm-project\llvm\lib\Support\Windows\Signals.inc:425:0
# |  #1 0x00007ffc2945bc31 (C:\WINDOWS\SYSTEM32\ucrtbased.dll+0x6bc31)
# |  #2 0x00007ffc2945d889 (C:\WINDOWS\SYSTEM32\ucrtbased.dll+0x6d889)
# |  #3 0x00007ffc294630bf (C:\WINDOWS\SYSTEM32\ucrtbased.dll+0x730bf)
# |  #4 0x00007ffc29461091 (C:\WINDOWS\SYSTEM32\ucrtbased.dll+0x71091)
# |  #5 0x00007ffc29463a1f (C:\WINDOWS\SYSTEM32\ucrtbased.dll+0x73a1f)
# |  #6 0x00007ff712628691 F:\source\llvm-project\llvm\include\llvm\Support\Casting.h:578:0
# |  #7 0x00007ff716019f2c pushTemporaryCleanup F:\source\llvm-project\clang\lib\CodeGen\CGExpr.cpp:352:0
# |  #8 0x00007ff71600c8d8 clang::CodeGen::CodeGenFunction::EmitMaterializeTemporaryExpr(class clang::MaterializeTemporaryExpr const *) F:\source\llvm-project\clang\lib\CodeGen\CGExpr.cpp:588:0
# |  #9 0x00007ff715ff8f7c clang::CodeGen::CodeGenFunction::EmitLValueHelper(class clang::Expr const *, enum clang::CodeGen::KnownNonNull_t) F:\source\llvm-project\clang\lib\CodeGen\CGExpr.cpp:1654:0
# | #10 0x00007ff715ff7e2c clang::CodeGen::CodeGenFunction::EmitLValue(class clang::Expr const *, enum clang::CodeGen::KnownNonNull_t) F:\source\llvm-project\clang\lib\CodeGen\CGExpr.cpp:1495:0
# | #11 0x00007ff715ff92e4 clang::CodeGen::CodeGenFunction::EmitCheckedLValue(class clang::Expr const *, enum clang::CodeGen::CodeGenFunction::TypeCheckKind) F:\source\llvm-project\clang\lib\CodeGen\CGExpr.cpp:1463:0
# | #12 0x00007ff71600896a clang::CodeGen::CodeGenFunction::EmitMemberExpr(class clang::MemberExpr const *) F:\source\llvm-project\clang\lib\CodeGen\CGExpr.cpp:4654:0
# | #13 0x00007ff715ff8d7c clang::CodeGen::CodeGenFunction::EmitLValueHelper(class clang::Expr const *, enum clang::CodeGen::KnownNonNull_t) F:\source\llvm-project\clang\lib\CodeGen\CGExpr.cpp:1628:0
# | #14 0x00007ff715ff7e2c clang::CodeGen::CodeGenFunction::EmitLValue(class clang::Expr const *, enum clang::CodeGen::KnownNonNull_t) F:\source\llvm-project\clang\lib\CodeGen\CGExpr.cpp:1495:0
# | #15 0x00007ff715ff92e4 clang::CodeGen::CodeGenFunction::EmitCheckedLValue(class clang::Expr const *, enum clang::CodeGen::CodeGenFunction::TypeCheckKind) F:\source\llvm-project\clang\lib\CodeGen\CGExpr.cpp:1463:0
# | #16 0x00007ff71920de7f `anonymous namespace'::ScalarExprEmitter::EmitCheckedLValue F:\source\llvm-project\clang\lib\CodeGen\CGExprScalar.cpp:255:0
# | #17 0x00007ff71920e880 `anonymous namespace'::ScalarExprEmitter::EmitLoadOfLValue F:\source\llvm-project\clang\lib\CodeGen\CGExprScalar.cpp:303:0
# | #18 0x00007ff719216202 `anonymous namespace'::ScalarExprEmitter::VisitMemberExpr F:\source\llvm-project\clang\lib\CodeGen\CGExprScalar.cpp:1947:0
# | #19 0x00007ff71920a31d clang::StmtVisitorBase<std::add_pointer,`anonymous namespace'::ScalarExprEmitter,llvm::Value *>::Visit F:\source\llvm-project\llvm\out\build\x64-Debug\tools\clang\include\clang\AST\StmtNodes.inc:310:0
# | #20 0x00007ff719212a6c `anonymous namespace'::ScalarExprEmitter::Visit F:\source\llvm-project\clang\lib\CodeGen\CGExprScalar.cpp:422:0
# | #21 0x00007ff719219a1a `anonymous namespace'::ScalarExprEmitter::VisitCastExpr F:\source\llvm-project\clang\lib\CodeGen\CGExprScalar.cpp:2505:0
# | #22 0x00007ff71920c0de clang::StmtVisitorBase<std::add_pointer,`anonymous namespace'::ScalarExprEmitter,llvm::Value *>::VisitImplicitCastExpr F:\source\llvm-project\llvm\out\build\x64-Debug\tools\clang\include\clang\AST\StmtNodes.inc:522:0
# | #23 0x00007ff71920a65d clang::StmtVisitorBase<std::add_pointer,`anonymous namespace'::ScalarExprEmitter,llvm::Value *>::Visit F:\source\llvm-project\llvm\out\build\x64-Debug\tools\clang\include\clang\AST\StmtNodes.inc:522:0
# | #24 0x00007ff719212a6c `anonymous namespace'::ScalarExprEmitter::Visit F:\source\llvm-project\clang\lib\CodeGen\CGExprScalar.cpp:422:0
# | #25 0x00007ff7192226de `anonymous namespace'::ScalarExprEmitter::VisitExprWithCleanups F:\source\llvm-project\clang\lib\CodeGen\CGExprScalar.cpp:2716:0
# | #26 0x00007ff71920a46f clang::StmtVisitorBase<std::add_pointer,`anonymous namespace'::ScalarExprEmitter,llvm::Value *>::Visit F:\source\llvm-project\llvm\out\build\x64-Debug\tools\clang\include\clang\AST\StmtNodes.inc:392:0
# | #27 0x00007ff719212a6c `anonymous namespace'::ScalarExprEmitter::Visit F:\source\llvm-project\clang\lib\CodeGen\CGExprScalar.cpp:422:0
# | #28 0x00007ff719207a4d clang::CodeGen::CodeGenFunction::EmitScalarExpr(class clang::Expr const *, bool) F:\source\llvm-project\clang\lib\CodeGen\CGExprScalar.cpp:5492:0
# | #29 0x00007ff715e7de2c clang::CodeGen::CodeGenFunction::EmitScalarInit(class clang::Expr const *, class clang::ValueDecl const *, class clang::CodeGen::LValue, bool) F:\source\llvm-project\clang\lib\CodeGen\CGDecl.cpp:797:0
# | #30 0x00007ff715e7ce3f clang::CodeGen::CodeGenFunction::EmitExprAsInit(class clang::Expr const *, class clang::ValueDecl const *, class clang::CodeGen::LValue, bool) F:\source\llvm-project\clang\lib\CodeGen\CGDecl.cpp:2016:0
# | #31 0x00007ff715e804c9 clang::CodeGen::CodeGenFunction::EmitAutoVarInit(class clang::CodeGen::CodeGenFunction::AutoVarEmission const &) F:\source\llvm-project\clang\lib\CodeGen\CGDecl.cpp:1978:0
# | #32 0x00007ff715e7e869 clang::CodeGen::CodeGenFunction::EmitAutoVarDecl(class clang::VarDecl const &) F:\source\llvm-project\clang\lib\CodeGen\CGDecl.cpp:1350:0
# | #33 0x00007ff715e7dd91 clang::CodeGen::CodeGenFunction::EmitVarDecl(class clang::VarDecl const &) F:\source\llvm-project\clang\lib\CodeGen\CGDecl.cpp:219:0
# | #34 0x00007ff715e7d8a3 clang::CodeGen::CodeGenFunction::EmitDecl(class clang::Decl const &) F:\source\llvm-project\clang\lib\CodeGen\CGDecl.cpp:164:0
# | #35 0x00007ff715fd2bf7 clang::CodeGen::CodeGenFunction::EmitDeclStmt(class clang::DeclStmt const &) F:\source\llvm-project\clang\lib\CodeGen\CGStmt.cpp:1573:0
# | #36 0x00007ff715fce329 clang::CodeGen::CodeGenFunction::EmitSimpleStmt(class clang::Stmt const *, class llvm::ArrayRef<class clang::Attr const *>) F:\source\llvm-project\clang\lib\CodeGen\CGStmt.cpp:463:0
# | #37 0x00007ff715fccd6e clang::CodeGen::CodeGenFunction::EmitStmt(class clang::Stmt const *, class llvm::ArrayRef<class clang::Attr const *>) F:\source\llvm-project\clang\lib\CodeGen\CGStmt.cpp:65:0
# | #38 0x00007ff715fceb96 clang::CodeGen::CodeGenFunction::EmitCompoundStmtWithoutScope(class clang::CompoundStmt const &, bool, class clang::CodeGen::AggValueSlot) F:\source\llvm-project\clang\lib\CodeGen\CGStmt.cpp:553:0
# | #39 0x00007ff715fb4a5b clang::CodeGen::CodeGenFunction::EmitFunctionBody(class clang::Stmt const *) F:\source\llvm-project\clang\lib\CodeGen\CodeGenFunction.cpp:1307:0
# | #40 0x00007ff715fab1d9 clang::CodeGen::CodeGenFunction::GenerateCode(class clang::GlobalDecl, class llvm::Function *, class clang::CodeGen::CGFunctionInfo const &) F:\source\llvm-project\clang\lib\CodeGen\CodeGenFunction.cpp:1533:0
# | #41 0x00007ff713ea5b71 clang::CodeGen::CodeGenModule::EmitGlobalFunctionDefinition(class clang::GlobalDecl, class llvm::GlobalValue *) F:\source\llvm-project\clang\lib\CodeGen\CodeGenModule.cpp:5939:0
# | #42 0x00007ff713ea581f clang::CodeGen::CodeGenModule::EmitGlobalDefinition(class clang::GlobalDecl, class llvm::GlobalValue *) F:\source\llvm-project\clang\lib\CodeGen\CodeGenModule.cpp:4117:0
# | #43 0x00007ff713e9c3a4 clang::CodeGen::CodeGenModule::EmitGlobal(class clang::GlobalDecl) F:\source\llvm-project\clang\lib\CodeGen\CodeGenModule.cpp:3829:0
# | #44 0x00007ff713e9402c clang::CodeGen::CodeGenModule::EmitTopLevelDecl(class clang::Decl *) F:\source\llvm-project\clang\lib\CodeGen\CodeGenModule.cpp:6824:0
# | #45 0x00007ff718351012 `anonymous namespace'::CodeGeneratorImpl::HandleTopLevelDecl F:\source\llvm-project\clang\lib\CodeGen\ModuleBuilder.cpp:190:0
# | #46 0x00007ff7147495d4 clang::BackendConsumer::HandleTopLevelDecl(class clang::DeclGroupRef) F:\source\llvm-project\clang\lib\CodeGen\CodeGenAction.cpp:199:0
# | #47 0x00007ff716a377c9 clang::ParseAST(class clang::Sema &, bool, bool) F:\source\llvm-project\clang\lib\Parse\ParseAST.cpp:167:0
# | #48 0x00007ff71433b522 clang::ASTFrontendAction::ExecuteAction(void) F:\source\llvm-project\clang\lib\Frontend\FrontendAction.cpp:1192:0
# | #49 0x00007ff714747927 clang::CodeGenAction::ExecuteAction(void) F:\source\llvm-project\clang\lib\CodeGen\CodeGenAction.cpp:1146:0
# | #50 0x00007ff71433ae0f clang::FrontendAction::Execute(void) F:\source\llvm-project\clang\lib\Frontend\FrontendAction.cpp:1078:0
# | #51 0x00007ff7127924a6 clang::CompilerInstance::ExecuteAction(class clang::FrontendAction &) F:\source\llvm-project\clang\lib\Frontend\CompilerInstance.cpp:1061:0
# | #52 0x00007ff712911ea5 clang::ExecuteCompilerInvocation(class clang::CompilerInstance *) F:\source\llvm-project\clang\lib\FrontendTool\ExecuteCompilerInvocation.cpp:280:0
# | #53 0x00007ff711c94b3f cc1_main(class llvm::ArrayRef<char const *>, char const *, void *) F:\source\llvm-project\clang\tools\driver\cc1_main.cpp:232:0
# | #54 0x00007ff711c8310e ExecuteCC1Tool F:\source\llvm-project\clang\tools\driver\driver.cpp:215:0
# | #55 0x00007ff711c83923 clang_main(int, char **, struct llvm::ToolContext const &) F:\source\llvm-project\clang\tools\driver\driver.cpp:256:0
# | #56 0x00007ff711cbebf6 main F:\source\llvm-project\llvm\out\build\x64-Debug\tools\clang\tools\driver\clang-driver.cpp:17:0
# | #57 0x00007ff71d3c0fb9 invoke_main D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:79:0
# | #58 0x00007ff71d3c10f2 __scrt_common_main_seh D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:288:0
# | #59 0x00007ff71d3c117e __scrt_common_main D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:331:0
# | #60 0x00007ff71d3c119e mainCRTStartup D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_main.cpp:17:0
# | #61 0x00007ffcc2ea7344 (C:\WINDOWS\System32\KERNEL32.DLL+0x17344)
# | #62 0x00007ffcc4a5cc91 (C:\WINDOWS\SYSTEM32\ntdll.dll+0x4cc91)
# `-----------------------------

so additional work is required to teach CodeGen how to handle the AST pattern. Alternatively, if this is undefined behavior we wish to define for our implementation, we should document it in the language extensions manual explicitly.

llvmbot commented 2 months ago

@llvm/issue-subscribers-clang-frontend

Author: Aaron Ballman (AaronBallman)

While investigating whether Clang properly implements [WG14 N1285](https://www.open-std.org/jtc1/sc22/wg14/www/docs/n1285.htm) (the factored approach), I found that Clang does not correctly materialize a temporary for the code that changed behavior: ``` struct X { int a[5]; } f(); int *p = f().a; printf("%p\n", p); ``` https://godbolt.org/z/6q6bsabsj In C11, that is an invalid use of a materialized temporary; in C99 it was required to work. Clang does not attempt to form a materialized temporary because of the language version check in: https://github.com/llvm/llvm-project/blob/c1bde0a2cb640b3607e9568b9a57b292e1f82666/clang/lib/Sema/SemaInit.cpp#L8667 Changing this to also materialize the temporary in C11 and later causes failed assertions in CodeGen: ``` # RUN: at line 1 f:\source\llvm-project\llvm\out\build\x64-debug\bin\clang.exe -cc1 -internal-isystem F:\source\llvm-project\llvm\out\build\x64-Debug\lib\clang\19\include -nostdsysteminc -triple aarch64_be-linux-gnu -ffreestanding -emit-llvm -O0 -o - F:\source\llvm-project\clang\test\CodeGen\arm64-be-hfa-vararg.c | f:\source\llvm-project\llvm\out\build\x64-debug\bin\filecheck.exe F:\source\llvm-project\clang\test\CodeGen\arm64-be-hfa-vararg.c # executed command: 'f:\source\llvm-project\llvm\out\build\x64-debug\bin\clang.exe' -cc1 -internal-isystem 'F:\source\llvm-project\llvm\out\build\x64-Debug\lib\clang\19\include' -nostdsysteminc -triple aarch64_be-linux-gnu -ffreestanding -emit-llvm -O0 -o - 'F:\source\llvm-project\clang\test\CodeGen\arm64-be-hfa-vararg.c' # .---command stderr------------ # | Assertion failed: isa<To>(Val) && "cast<Ty>() argument of incompatible type!", file F:\source\llvm-project\llvm\include\llvm/Support/Casting.h, line 578 # | PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace, preprocessed source, and associated run script. # | Stack dump: # | 0. Program arguments: f:\\source\\llvm-project\\llvm\\out\\build\\x64-debug\\bin\\clang.exe -cc1 -internal-isystem F:\\source\\llvm-project\\llvm\\out\\build\\x64-Debug\\lib\\clang\\19\\include -nostdsysteminc -triple aarch64_be-linux-gnu -ffreestanding -emit-llvm -O0 -o - F:\\source\\llvm-project\\clang\\test\\CodeGen\\arm64-be-hfa-vararg.c # | 1. <eof> parser at end of file # | 2. F:\source\llvm-project\clang\test\CodeGen\arm64-be-hfa-vararg.c:6:8: LLVM IR generation of declaration 'callee' # | 3. F:\source\llvm-project\clang\test\CodeGen\arm64-be-hfa-vararg.c:6:8: Generating code for declaration 'callee' # | Exception Code: 0x80000003 # | #0 0x00007ff7124ddebc HandleAbort F:\source\llvm-project\llvm\lib\Support\Windows\Signals.inc:425:0 # | #1 0x00007ffc2945bc31 (C:\WINDOWS\SYSTEM32\ucrtbased.dll+0x6bc31) # | #2 0x00007ffc2945d889 (C:\WINDOWS\SYSTEM32\ucrtbased.dll+0x6d889) # | #3 0x00007ffc294630bf (C:\WINDOWS\SYSTEM32\ucrtbased.dll+0x730bf) # | #4 0x00007ffc29461091 (C:\WINDOWS\SYSTEM32\ucrtbased.dll+0x71091) # | #5 0x00007ffc29463a1f (C:\WINDOWS\SYSTEM32\ucrtbased.dll+0x73a1f) # | #6 0x00007ff712628691 F:\source\llvm-project\llvm\include\llvm\Support\Casting.h:578:0 # | #7 0x00007ff716019f2c pushTemporaryCleanup F:\source\llvm-project\clang\lib\CodeGen\CGExpr.cpp:352:0 # | #8 0x00007ff71600c8d8 clang::CodeGen::CodeGenFunction::EmitMaterializeTemporaryExpr(class clang::MaterializeTemporaryExpr const *) F:\source\llvm-project\clang\lib\CodeGen\CGExpr.cpp:588:0 # | #9 0x00007ff715ff8f7c clang::CodeGen::CodeGenFunction::EmitLValueHelper(class clang::Expr const *, enum clang::CodeGen::KnownNonNull_t) F:\source\llvm-project\clang\lib\CodeGen\CGExpr.cpp:1654:0 # | #10 0x00007ff715ff7e2c clang::CodeGen::CodeGenFunction::EmitLValue(class clang::Expr const *, enum clang::CodeGen::KnownNonNull_t) F:\source\llvm-project\clang\lib\CodeGen\CGExpr.cpp:1495:0 # | #11 0x00007ff715ff92e4 clang::CodeGen::CodeGenFunction::EmitCheckedLValue(class clang::Expr const *, enum clang::CodeGen::CodeGenFunction::TypeCheckKind) F:\source\llvm-project\clang\lib\CodeGen\CGExpr.cpp:1463:0 # | #12 0x00007ff71600896a clang::CodeGen::CodeGenFunction::EmitMemberExpr(class clang::MemberExpr const *) F:\source\llvm-project\clang\lib\CodeGen\CGExpr.cpp:4654:0 # | #13 0x00007ff715ff8d7c clang::CodeGen::CodeGenFunction::EmitLValueHelper(class clang::Expr const *, enum clang::CodeGen::KnownNonNull_t) F:\source\llvm-project\clang\lib\CodeGen\CGExpr.cpp:1628:0 # | #14 0x00007ff715ff7e2c clang::CodeGen::CodeGenFunction::EmitLValue(class clang::Expr const *, enum clang::CodeGen::KnownNonNull_t) F:\source\llvm-project\clang\lib\CodeGen\CGExpr.cpp:1495:0 # | #15 0x00007ff715ff92e4 clang::CodeGen::CodeGenFunction::EmitCheckedLValue(class clang::Expr const *, enum clang::CodeGen::CodeGenFunction::TypeCheckKind) F:\source\llvm-project\clang\lib\CodeGen\CGExpr.cpp:1463:0 # | #16 0x00007ff71920de7f `anonymous namespace'::ScalarExprEmitter::EmitCheckedLValue F:\source\llvm-project\clang\lib\CodeGen\CGExprScalar.cpp:255:0 # | #17 0x00007ff71920e880 `anonymous namespace'::ScalarExprEmitter::EmitLoadOfLValue F:\source\llvm-project\clang\lib\CodeGen\CGExprScalar.cpp:303:0 # | #18 0x00007ff719216202 `anonymous namespace'::ScalarExprEmitter::VisitMemberExpr F:\source\llvm-project\clang\lib\CodeGen\CGExprScalar.cpp:1947:0 # | #19 0x00007ff71920a31d clang::StmtVisitorBase<std::add_pointer,`anonymous namespace'::ScalarExprEmitter,llvm::Value *>::Visit F:\source\llvm-project\llvm\out\build\x64-Debug\tools\clang\include\clang\AST\StmtNodes.inc:310:0 # | #20 0x00007ff719212a6c `anonymous namespace'::ScalarExprEmitter::Visit F:\source\llvm-project\clang\lib\CodeGen\CGExprScalar.cpp:422:0 # | #21 0x00007ff719219a1a `anonymous namespace'::ScalarExprEmitter::VisitCastExpr F:\source\llvm-project\clang\lib\CodeGen\CGExprScalar.cpp:2505:0 # | #22 0x00007ff71920c0de clang::StmtVisitorBase<std::add_pointer,`anonymous namespace'::ScalarExprEmitter,llvm::Value *>::VisitImplicitCastExpr F:\source\llvm-project\llvm\out\build\x64-Debug\tools\clang\include\clang\AST\StmtNodes.inc:522:0 # | #23 0x00007ff71920a65d clang::StmtVisitorBase<std::add_pointer,`anonymous namespace'::ScalarExprEmitter,llvm::Value *>::Visit F:\source\llvm-project\llvm\out\build\x64-Debug\tools\clang\include\clang\AST\StmtNodes.inc:522:0 # | #24 0x00007ff719212a6c `anonymous namespace'::ScalarExprEmitter::Visit F:\source\llvm-project\clang\lib\CodeGen\CGExprScalar.cpp:422:0 # | #25 0x00007ff7192226de `anonymous namespace'::ScalarExprEmitter::VisitExprWithCleanups F:\source\llvm-project\clang\lib\CodeGen\CGExprScalar.cpp:2716:0 # | #26 0x00007ff71920a46f clang::StmtVisitorBase<std::add_pointer,`anonymous namespace'::ScalarExprEmitter,llvm::Value *>::Visit F:\source\llvm-project\llvm\out\build\x64-Debug\tools\clang\include\clang\AST\StmtNodes.inc:392:0 # | #27 0x00007ff719212a6c `anonymous namespace'::ScalarExprEmitter::Visit F:\source\llvm-project\clang\lib\CodeGen\CGExprScalar.cpp:422:0 # | #28 0x00007ff719207a4d clang::CodeGen::CodeGenFunction::EmitScalarExpr(class clang::Expr const *, bool) F:\source\llvm-project\clang\lib\CodeGen\CGExprScalar.cpp:5492:0 # | #29 0x00007ff715e7de2c clang::CodeGen::CodeGenFunction::EmitScalarInit(class clang::Expr const *, class clang::ValueDecl const *, class clang::CodeGen::LValue, bool) F:\source\llvm-project\clang\lib\CodeGen\CGDecl.cpp:797:0 # | #30 0x00007ff715e7ce3f clang::CodeGen::CodeGenFunction::EmitExprAsInit(class clang::Expr const *, class clang::ValueDecl const *, class clang::CodeGen::LValue, bool) F:\source\llvm-project\clang\lib\CodeGen\CGDecl.cpp:2016:0 # | #31 0x00007ff715e804c9 clang::CodeGen::CodeGenFunction::EmitAutoVarInit(class clang::CodeGen::CodeGenFunction::AutoVarEmission const &) F:\source\llvm-project\clang\lib\CodeGen\CGDecl.cpp:1978:0 # | #32 0x00007ff715e7e869 clang::CodeGen::CodeGenFunction::EmitAutoVarDecl(class clang::VarDecl const &) F:\source\llvm-project\clang\lib\CodeGen\CGDecl.cpp:1350:0 # | #33 0x00007ff715e7dd91 clang::CodeGen::CodeGenFunction::EmitVarDecl(class clang::VarDecl const &) F:\source\llvm-project\clang\lib\CodeGen\CGDecl.cpp:219:0 # | #34 0x00007ff715e7d8a3 clang::CodeGen::CodeGenFunction::EmitDecl(class clang::Decl const &) F:\source\llvm-project\clang\lib\CodeGen\CGDecl.cpp:164:0 # | #35 0x00007ff715fd2bf7 clang::CodeGen::CodeGenFunction::EmitDeclStmt(class clang::DeclStmt const &) F:\source\llvm-project\clang\lib\CodeGen\CGStmt.cpp:1573:0 # | #36 0x00007ff715fce329 clang::CodeGen::CodeGenFunction::EmitSimpleStmt(class clang::Stmt const *, class llvm::ArrayRef<class clang::Attr const *>) F:\source\llvm-project\clang\lib\CodeGen\CGStmt.cpp:463:0 # | #37 0x00007ff715fccd6e clang::CodeGen::CodeGenFunction::EmitStmt(class clang::Stmt const *, class llvm::ArrayRef<class clang::Attr const *>) F:\source\llvm-project\clang\lib\CodeGen\CGStmt.cpp:65:0 # | #38 0x00007ff715fceb96 clang::CodeGen::CodeGenFunction::EmitCompoundStmtWithoutScope(class clang::CompoundStmt const &, bool, class clang::CodeGen::AggValueSlot) F:\source\llvm-project\clang\lib\CodeGen\CGStmt.cpp:553:0 # | #39 0x00007ff715fb4a5b clang::CodeGen::CodeGenFunction::EmitFunctionBody(class clang::Stmt const *) F:\source\llvm-project\clang\lib\CodeGen\CodeGenFunction.cpp:1307:0 # | #40 0x00007ff715fab1d9 clang::CodeGen::CodeGenFunction::GenerateCode(class clang::GlobalDecl, class llvm::Function *, class clang::CodeGen::CGFunctionInfo const &) F:\source\llvm-project\clang\lib\CodeGen\CodeGenFunction.cpp:1533:0 # | #41 0x00007ff713ea5b71 clang::CodeGen::CodeGenModule::EmitGlobalFunctionDefinition(class clang::GlobalDecl, class llvm::GlobalValue *) F:\source\llvm-project\clang\lib\CodeGen\CodeGenModule.cpp:5939:0 # | #42 0x00007ff713ea581f clang::CodeGen::CodeGenModule::EmitGlobalDefinition(class clang::GlobalDecl, class llvm::GlobalValue *) F:\source\llvm-project\clang\lib\CodeGen\CodeGenModule.cpp:4117:0 # | #43 0x00007ff713e9c3a4 clang::CodeGen::CodeGenModule::EmitGlobal(class clang::GlobalDecl) F:\source\llvm-project\clang\lib\CodeGen\CodeGenModule.cpp:3829:0 # | #44 0x00007ff713e9402c clang::CodeGen::CodeGenModule::EmitTopLevelDecl(class clang::Decl *) F:\source\llvm-project\clang\lib\CodeGen\CodeGenModule.cpp:6824:0 # | #45 0x00007ff718351012 `anonymous namespace'::CodeGeneratorImpl::HandleTopLevelDecl F:\source\llvm-project\clang\lib\CodeGen\ModuleBuilder.cpp:190:0 # | #46 0x00007ff7147495d4 clang::BackendConsumer::HandleTopLevelDecl(class clang::DeclGroupRef) F:\source\llvm-project\clang\lib\CodeGen\CodeGenAction.cpp:199:0 # | #47 0x00007ff716a377c9 clang::ParseAST(class clang::Sema &, bool, bool) F:\source\llvm-project\clang\lib\Parse\ParseAST.cpp:167:0 # | #48 0x00007ff71433b522 clang::ASTFrontendAction::ExecuteAction(void) F:\source\llvm-project\clang\lib\Frontend\FrontendAction.cpp:1192:0 # | #49 0x00007ff714747927 clang::CodeGenAction::ExecuteAction(void) F:\source\llvm-project\clang\lib\CodeGen\CodeGenAction.cpp:1146:0 # | #50 0x00007ff71433ae0f clang::FrontendAction::Execute(void) F:\source\llvm-project\clang\lib\Frontend\FrontendAction.cpp:1078:0 # | #51 0x00007ff7127924a6 clang::CompilerInstance::ExecuteAction(class clang::FrontendAction &) F:\source\llvm-project\clang\lib\Frontend\CompilerInstance.cpp:1061:0 # | #52 0x00007ff712911ea5 clang::ExecuteCompilerInvocation(class clang::CompilerInstance *) F:\source\llvm-project\clang\lib\FrontendTool\ExecuteCompilerInvocation.cpp:280:0 # | #53 0x00007ff711c94b3f cc1_main(class llvm::ArrayRef<char const *>, char const *, void *) F:\source\llvm-project\clang\tools\driver\cc1_main.cpp:232:0 # | #54 0x00007ff711c8310e ExecuteCC1Tool F:\source\llvm-project\clang\tools\driver\driver.cpp:215:0 # | #55 0x00007ff711c83923 clang_main(int, char **, struct llvm::ToolContext const &) F:\source\llvm-project\clang\tools\driver\driver.cpp:256:0 # | #56 0x00007ff711cbebf6 main F:\source\llvm-project\llvm\out\build\x64-Debug\tools\clang\tools\driver\clang-driver.cpp:17:0 # | #57 0x00007ff71d3c0fb9 invoke_main D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:79:0 # | #58 0x00007ff71d3c10f2 __scrt_common_main_seh D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:288:0 # | #59 0x00007ff71d3c117e __scrt_common_main D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:331:0 # | #60 0x00007ff71d3c119e mainCRTStartup D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_main.cpp:17:0 # | #61 0x00007ffcc2ea7344 (C:\WINDOWS\System32\KERNEL32.DLL+0x17344) # | #62 0x00007ffcc4a5cc91 (C:\WINDOWS\SYSTEM32\ntdll.dll+0x4cc91) # `----------------------------- ``` so additional work is required to teach CodeGen how to handle the AST pattern. Alternatively, if this is undefined behavior we wish to define for our implementation, we should document it in the language extensions manual explicitly.
llvmbot commented 2 months ago

@llvm/issue-subscribers-c11

Author: Aaron Ballman (AaronBallman)

While investigating whether Clang properly implements [WG14 N1285](https://www.open-std.org/jtc1/sc22/wg14/www/docs/n1285.htm) (the factored approach), I found that Clang does not correctly materialize a temporary for the code that changed behavior: ``` struct X { int a[5]; } f(); int *p = f().a; printf("%p\n", p); ``` https://godbolt.org/z/6q6bsabsj In C11, that is an invalid use of a materialized temporary; in C99 it was required to work. Clang does not attempt to form a materialized temporary because of the language version check in: https://github.com/llvm/llvm-project/blob/c1bde0a2cb640b3607e9568b9a57b292e1f82666/clang/lib/Sema/SemaInit.cpp#L8667 Changing this to also materialize the temporary in C11 and later causes failed assertions in CodeGen: ``` # RUN: at line 1 f:\source\llvm-project\llvm\out\build\x64-debug\bin\clang.exe -cc1 -internal-isystem F:\source\llvm-project\llvm\out\build\x64-Debug\lib\clang\19\include -nostdsysteminc -triple aarch64_be-linux-gnu -ffreestanding -emit-llvm -O0 -o - F:\source\llvm-project\clang\test\CodeGen\arm64-be-hfa-vararg.c | f:\source\llvm-project\llvm\out\build\x64-debug\bin\filecheck.exe F:\source\llvm-project\clang\test\CodeGen\arm64-be-hfa-vararg.c # executed command: 'f:\source\llvm-project\llvm\out\build\x64-debug\bin\clang.exe' -cc1 -internal-isystem 'F:\source\llvm-project\llvm\out\build\x64-Debug\lib\clang\19\include' -nostdsysteminc -triple aarch64_be-linux-gnu -ffreestanding -emit-llvm -O0 -o - 'F:\source\llvm-project\clang\test\CodeGen\arm64-be-hfa-vararg.c' # .---command stderr------------ # | Assertion failed: isa<To>(Val) && "cast<Ty>() argument of incompatible type!", file F:\source\llvm-project\llvm\include\llvm/Support/Casting.h, line 578 # | PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace, preprocessed source, and associated run script. # | Stack dump: # | 0. Program arguments: f:\\source\\llvm-project\\llvm\\out\\build\\x64-debug\\bin\\clang.exe -cc1 -internal-isystem F:\\source\\llvm-project\\llvm\\out\\build\\x64-Debug\\lib\\clang\\19\\include -nostdsysteminc -triple aarch64_be-linux-gnu -ffreestanding -emit-llvm -O0 -o - F:\\source\\llvm-project\\clang\\test\\CodeGen\\arm64-be-hfa-vararg.c # | 1. <eof> parser at end of file # | 2. F:\source\llvm-project\clang\test\CodeGen\arm64-be-hfa-vararg.c:6:8: LLVM IR generation of declaration 'callee' # | 3. F:\source\llvm-project\clang\test\CodeGen\arm64-be-hfa-vararg.c:6:8: Generating code for declaration 'callee' # | Exception Code: 0x80000003 # | #0 0x00007ff7124ddebc HandleAbort F:\source\llvm-project\llvm\lib\Support\Windows\Signals.inc:425:0 # | #1 0x00007ffc2945bc31 (C:\WINDOWS\SYSTEM32\ucrtbased.dll+0x6bc31) # | #2 0x00007ffc2945d889 (C:\WINDOWS\SYSTEM32\ucrtbased.dll+0x6d889) # | #3 0x00007ffc294630bf (C:\WINDOWS\SYSTEM32\ucrtbased.dll+0x730bf) # | #4 0x00007ffc29461091 (C:\WINDOWS\SYSTEM32\ucrtbased.dll+0x71091) # | #5 0x00007ffc29463a1f (C:\WINDOWS\SYSTEM32\ucrtbased.dll+0x73a1f) # | #6 0x00007ff712628691 F:\source\llvm-project\llvm\include\llvm\Support\Casting.h:578:0 # | #7 0x00007ff716019f2c pushTemporaryCleanup F:\source\llvm-project\clang\lib\CodeGen\CGExpr.cpp:352:0 # | #8 0x00007ff71600c8d8 clang::CodeGen::CodeGenFunction::EmitMaterializeTemporaryExpr(class clang::MaterializeTemporaryExpr const *) F:\source\llvm-project\clang\lib\CodeGen\CGExpr.cpp:588:0 # | #9 0x00007ff715ff8f7c clang::CodeGen::CodeGenFunction::EmitLValueHelper(class clang::Expr const *, enum clang::CodeGen::KnownNonNull_t) F:\source\llvm-project\clang\lib\CodeGen\CGExpr.cpp:1654:0 # | #10 0x00007ff715ff7e2c clang::CodeGen::CodeGenFunction::EmitLValue(class clang::Expr const *, enum clang::CodeGen::KnownNonNull_t) F:\source\llvm-project\clang\lib\CodeGen\CGExpr.cpp:1495:0 # | #11 0x00007ff715ff92e4 clang::CodeGen::CodeGenFunction::EmitCheckedLValue(class clang::Expr const *, enum clang::CodeGen::CodeGenFunction::TypeCheckKind) F:\source\llvm-project\clang\lib\CodeGen\CGExpr.cpp:1463:0 # | #12 0x00007ff71600896a clang::CodeGen::CodeGenFunction::EmitMemberExpr(class clang::MemberExpr const *) F:\source\llvm-project\clang\lib\CodeGen\CGExpr.cpp:4654:0 # | #13 0x00007ff715ff8d7c clang::CodeGen::CodeGenFunction::EmitLValueHelper(class clang::Expr const *, enum clang::CodeGen::KnownNonNull_t) F:\source\llvm-project\clang\lib\CodeGen\CGExpr.cpp:1628:0 # | #14 0x00007ff715ff7e2c clang::CodeGen::CodeGenFunction::EmitLValue(class clang::Expr const *, enum clang::CodeGen::KnownNonNull_t) F:\source\llvm-project\clang\lib\CodeGen\CGExpr.cpp:1495:0 # | #15 0x00007ff715ff92e4 clang::CodeGen::CodeGenFunction::EmitCheckedLValue(class clang::Expr const *, enum clang::CodeGen::CodeGenFunction::TypeCheckKind) F:\source\llvm-project\clang\lib\CodeGen\CGExpr.cpp:1463:0 # | #16 0x00007ff71920de7f `anonymous namespace'::ScalarExprEmitter::EmitCheckedLValue F:\source\llvm-project\clang\lib\CodeGen\CGExprScalar.cpp:255:0 # | #17 0x00007ff71920e880 `anonymous namespace'::ScalarExprEmitter::EmitLoadOfLValue F:\source\llvm-project\clang\lib\CodeGen\CGExprScalar.cpp:303:0 # | #18 0x00007ff719216202 `anonymous namespace'::ScalarExprEmitter::VisitMemberExpr F:\source\llvm-project\clang\lib\CodeGen\CGExprScalar.cpp:1947:0 # | #19 0x00007ff71920a31d clang::StmtVisitorBase<std::add_pointer,`anonymous namespace'::ScalarExprEmitter,llvm::Value *>::Visit F:\source\llvm-project\llvm\out\build\x64-Debug\tools\clang\include\clang\AST\StmtNodes.inc:310:0 # | #20 0x00007ff719212a6c `anonymous namespace'::ScalarExprEmitter::Visit F:\source\llvm-project\clang\lib\CodeGen\CGExprScalar.cpp:422:0 # | #21 0x00007ff719219a1a `anonymous namespace'::ScalarExprEmitter::VisitCastExpr F:\source\llvm-project\clang\lib\CodeGen\CGExprScalar.cpp:2505:0 # | #22 0x00007ff71920c0de clang::StmtVisitorBase<std::add_pointer,`anonymous namespace'::ScalarExprEmitter,llvm::Value *>::VisitImplicitCastExpr F:\source\llvm-project\llvm\out\build\x64-Debug\tools\clang\include\clang\AST\StmtNodes.inc:522:0 # | #23 0x00007ff71920a65d clang::StmtVisitorBase<std::add_pointer,`anonymous namespace'::ScalarExprEmitter,llvm::Value *>::Visit F:\source\llvm-project\llvm\out\build\x64-Debug\tools\clang\include\clang\AST\StmtNodes.inc:522:0 # | #24 0x00007ff719212a6c `anonymous namespace'::ScalarExprEmitter::Visit F:\source\llvm-project\clang\lib\CodeGen\CGExprScalar.cpp:422:0 # | #25 0x00007ff7192226de `anonymous namespace'::ScalarExprEmitter::VisitExprWithCleanups F:\source\llvm-project\clang\lib\CodeGen\CGExprScalar.cpp:2716:0 # | #26 0x00007ff71920a46f clang::StmtVisitorBase<std::add_pointer,`anonymous namespace'::ScalarExprEmitter,llvm::Value *>::Visit F:\source\llvm-project\llvm\out\build\x64-Debug\tools\clang\include\clang\AST\StmtNodes.inc:392:0 # | #27 0x00007ff719212a6c `anonymous namespace'::ScalarExprEmitter::Visit F:\source\llvm-project\clang\lib\CodeGen\CGExprScalar.cpp:422:0 # | #28 0x00007ff719207a4d clang::CodeGen::CodeGenFunction::EmitScalarExpr(class clang::Expr const *, bool) F:\source\llvm-project\clang\lib\CodeGen\CGExprScalar.cpp:5492:0 # | #29 0x00007ff715e7de2c clang::CodeGen::CodeGenFunction::EmitScalarInit(class clang::Expr const *, class clang::ValueDecl const *, class clang::CodeGen::LValue, bool) F:\source\llvm-project\clang\lib\CodeGen\CGDecl.cpp:797:0 # | #30 0x00007ff715e7ce3f clang::CodeGen::CodeGenFunction::EmitExprAsInit(class clang::Expr const *, class clang::ValueDecl const *, class clang::CodeGen::LValue, bool) F:\source\llvm-project\clang\lib\CodeGen\CGDecl.cpp:2016:0 # | #31 0x00007ff715e804c9 clang::CodeGen::CodeGenFunction::EmitAutoVarInit(class clang::CodeGen::CodeGenFunction::AutoVarEmission const &) F:\source\llvm-project\clang\lib\CodeGen\CGDecl.cpp:1978:0 # | #32 0x00007ff715e7e869 clang::CodeGen::CodeGenFunction::EmitAutoVarDecl(class clang::VarDecl const &) F:\source\llvm-project\clang\lib\CodeGen\CGDecl.cpp:1350:0 # | #33 0x00007ff715e7dd91 clang::CodeGen::CodeGenFunction::EmitVarDecl(class clang::VarDecl const &) F:\source\llvm-project\clang\lib\CodeGen\CGDecl.cpp:219:0 # | #34 0x00007ff715e7d8a3 clang::CodeGen::CodeGenFunction::EmitDecl(class clang::Decl const &) F:\source\llvm-project\clang\lib\CodeGen\CGDecl.cpp:164:0 # | #35 0x00007ff715fd2bf7 clang::CodeGen::CodeGenFunction::EmitDeclStmt(class clang::DeclStmt const &) F:\source\llvm-project\clang\lib\CodeGen\CGStmt.cpp:1573:0 # | #36 0x00007ff715fce329 clang::CodeGen::CodeGenFunction::EmitSimpleStmt(class clang::Stmt const *, class llvm::ArrayRef<class clang::Attr const *>) F:\source\llvm-project\clang\lib\CodeGen\CGStmt.cpp:463:0 # | #37 0x00007ff715fccd6e clang::CodeGen::CodeGenFunction::EmitStmt(class clang::Stmt const *, class llvm::ArrayRef<class clang::Attr const *>) F:\source\llvm-project\clang\lib\CodeGen\CGStmt.cpp:65:0 # | #38 0x00007ff715fceb96 clang::CodeGen::CodeGenFunction::EmitCompoundStmtWithoutScope(class clang::CompoundStmt const &, bool, class clang::CodeGen::AggValueSlot) F:\source\llvm-project\clang\lib\CodeGen\CGStmt.cpp:553:0 # | #39 0x00007ff715fb4a5b clang::CodeGen::CodeGenFunction::EmitFunctionBody(class clang::Stmt const *) F:\source\llvm-project\clang\lib\CodeGen\CodeGenFunction.cpp:1307:0 # | #40 0x00007ff715fab1d9 clang::CodeGen::CodeGenFunction::GenerateCode(class clang::GlobalDecl, class llvm::Function *, class clang::CodeGen::CGFunctionInfo const &) F:\source\llvm-project\clang\lib\CodeGen\CodeGenFunction.cpp:1533:0 # | #41 0x00007ff713ea5b71 clang::CodeGen::CodeGenModule::EmitGlobalFunctionDefinition(class clang::GlobalDecl, class llvm::GlobalValue *) F:\source\llvm-project\clang\lib\CodeGen\CodeGenModule.cpp:5939:0 # | #42 0x00007ff713ea581f clang::CodeGen::CodeGenModule::EmitGlobalDefinition(class clang::GlobalDecl, class llvm::GlobalValue *) F:\source\llvm-project\clang\lib\CodeGen\CodeGenModule.cpp:4117:0 # | #43 0x00007ff713e9c3a4 clang::CodeGen::CodeGenModule::EmitGlobal(class clang::GlobalDecl) F:\source\llvm-project\clang\lib\CodeGen\CodeGenModule.cpp:3829:0 # | #44 0x00007ff713e9402c clang::CodeGen::CodeGenModule::EmitTopLevelDecl(class clang::Decl *) F:\source\llvm-project\clang\lib\CodeGen\CodeGenModule.cpp:6824:0 # | #45 0x00007ff718351012 `anonymous namespace'::CodeGeneratorImpl::HandleTopLevelDecl F:\source\llvm-project\clang\lib\CodeGen\ModuleBuilder.cpp:190:0 # | #46 0x00007ff7147495d4 clang::BackendConsumer::HandleTopLevelDecl(class clang::DeclGroupRef) F:\source\llvm-project\clang\lib\CodeGen\CodeGenAction.cpp:199:0 # | #47 0x00007ff716a377c9 clang::ParseAST(class clang::Sema &, bool, bool) F:\source\llvm-project\clang\lib\Parse\ParseAST.cpp:167:0 # | #48 0x00007ff71433b522 clang::ASTFrontendAction::ExecuteAction(void) F:\source\llvm-project\clang\lib\Frontend\FrontendAction.cpp:1192:0 # | #49 0x00007ff714747927 clang::CodeGenAction::ExecuteAction(void) F:\source\llvm-project\clang\lib\CodeGen\CodeGenAction.cpp:1146:0 # | #50 0x00007ff71433ae0f clang::FrontendAction::Execute(void) F:\source\llvm-project\clang\lib\Frontend\FrontendAction.cpp:1078:0 # | #51 0x00007ff7127924a6 clang::CompilerInstance::ExecuteAction(class clang::FrontendAction &) F:\source\llvm-project\clang\lib\Frontend\CompilerInstance.cpp:1061:0 # | #52 0x00007ff712911ea5 clang::ExecuteCompilerInvocation(class clang::CompilerInstance *) F:\source\llvm-project\clang\lib\FrontendTool\ExecuteCompilerInvocation.cpp:280:0 # | #53 0x00007ff711c94b3f cc1_main(class llvm::ArrayRef<char const *>, char const *, void *) F:\source\llvm-project\clang\tools\driver\cc1_main.cpp:232:0 # | #54 0x00007ff711c8310e ExecuteCC1Tool F:\source\llvm-project\clang\tools\driver\driver.cpp:215:0 # | #55 0x00007ff711c83923 clang_main(int, char **, struct llvm::ToolContext const &) F:\source\llvm-project\clang\tools\driver\driver.cpp:256:0 # | #56 0x00007ff711cbebf6 main F:\source\llvm-project\llvm\out\build\x64-Debug\tools\clang\tools\driver\clang-driver.cpp:17:0 # | #57 0x00007ff71d3c0fb9 invoke_main D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:79:0 # | #58 0x00007ff71d3c10f2 __scrt_common_main_seh D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:288:0 # | #59 0x00007ff71d3c117e __scrt_common_main D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:331:0 # | #60 0x00007ff71d3c119e mainCRTStartup D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_main.cpp:17:0 # | #61 0x00007ffcc2ea7344 (C:\WINDOWS\System32\KERNEL32.DLL+0x17344) # | #62 0x00007ffcc4a5cc91 (C:\WINDOWS\SYSTEM32\ntdll.dll+0x4cc91) # `----------------------------- ``` so additional work is required to teach CodeGen how to handle the AST pattern. Alternatively, if this is undefined behavior we wish to define for our implementation, we should document it in the language extensions manual explicitly.
efriedma-quic commented 2 months ago

I think we do the "proper" MaterializeTemporaryExpr thing for C++, but for C we just kind of guess what temporaries we need in CodeGen. I think this dates back to the initial implementation of C++ codegen. It would probably simplify CodeGen significantly if we could rely on the existence of an MaterializeTemporaryExpr where appropriate.