https://github.com/adityankit updated https://github.com/llvm/llvm-project/pull/158199
>From a967a7ccf0fd8cc645226a4ba0da78ed8c121408 Mon Sep 17 00:00:00 2001 From: Aditya Chaudhary <aditya.chaudha...@ibm.com> Date: Thu, 11 Sep 2025 12:16:31 -0400 Subject: [PATCH] Disable -gsplit-dwarf as it is unsupported at the moment on AIX [clang][bytecode] Pass initializer along in `evaluateAsInitializer()` (#158056) We just called `getInit()`, which isn't always correct and used the wrong initializer in the module test case. --- clang/lib/AST/ByteCode/ByteCodeEmitter.h | 3 ++- clang/lib/AST/ByteCode/Compiler.cpp | 21 ++++++++++----------- clang/lib/AST/ByteCode/Compiler.h | 6 ++++-- clang/lib/AST/ByteCode/Context.cpp | 4 ++-- clang/lib/AST/ByteCode/Context.h | 3 ++- clang/lib/AST/ByteCode/EvalEmitter.cpp | 7 ++++--- clang/lib/AST/ByteCode/EvalEmitter.h | 6 ++++-- clang/lib/AST/ExprConstant.cpp | 2 +- clang/lib/Driver/ToolChains/Clang.cpp | 7 +++++++ clang/test/Driver/aix-gsplit-dwarf.c | 12 ++++++++++++ clang/test/Modules/added-visible-decls.cppm | 1 + 11 files changed, 49 insertions(+), 23 deletions(-) create mode 100644 clang/test/Driver/aix-gsplit-dwarf.c diff --git a/clang/lib/AST/ByteCode/ByteCodeEmitter.h b/clang/lib/AST/ByteCode/ByteCodeEmitter.h index d29db66325412..c050b299d8f61 100644 --- a/clang/lib/AST/ByteCode/ByteCodeEmitter.h +++ b/clang/lib/AST/ByteCode/ByteCodeEmitter.h @@ -46,7 +46,8 @@ class ByteCodeEmitter { /// Methods implemented by the compiler. virtual bool visitFunc(const FunctionDecl *E) = 0; virtual bool visitExpr(const Expr *E, bool DestroyToplevelScope) = 0; - virtual bool visitDeclAndReturn(const VarDecl *E, bool ConstantContext) = 0; + virtual bool visitDeclAndReturn(const VarDecl *VD, const Expr *Init, + bool ConstantContext) = 0; virtual bool visit(const Expr *E) = 0; virtual bool emitBool(bool V, const Expr *E) = 0; diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp index 3f7db39281358..78b74acc3789d 100644 --- a/clang/lib/AST/ByteCode/Compiler.cpp +++ b/clang/lib/AST/ByteCode/Compiler.cpp @@ -4714,7 +4714,8 @@ template <class Emitter> VarCreationState Compiler<Emitter>::visitDecl(const VarDecl *VD, bool IsConstexprUnknown) { - auto R = this->visitVarDecl(VD, /*Toplevel=*/true, IsConstexprUnknown); + auto R = this->visitVarDecl(VD, VD->getInit(), /*Toplevel=*/true, + IsConstexprUnknown); if (R.notCreated()) return R; @@ -4740,14 +4741,12 @@ VarCreationState Compiler<Emitter>::visitDecl(const VarDecl *VD, /// We get here from evaluateAsInitializer(). /// We need to evaluate the initializer and return its value. template <class Emitter> -bool Compiler<Emitter>::visitDeclAndReturn(const VarDecl *VD, +bool Compiler<Emitter>::visitDeclAndReturn(const VarDecl *VD, const Expr *Init, bool ConstantContext) { - // We only create variables if we're evaluating in a constant context. // Otherwise, just evaluate the initializer and return it. if (!ConstantContext) { DeclScope<Emitter> LS(this, VD); - const Expr *Init = VD->getInit(); if (!this->visit(Init)) return false; return this->emitRet(classify(Init).value_or(PT_Ptr), VD) && @@ -4755,7 +4754,7 @@ bool Compiler<Emitter>::visitDeclAndReturn(const VarDecl *VD, } LocalScope<Emitter> VDScope(this, VD); - if (!this->visitVarDecl(VD, /*Toplevel=*/true)) + if (!this->visitVarDecl(VD, Init, /*Toplevel=*/true)) return false; OptPrimType VarT = classify(VD->getType()); @@ -4802,9 +4801,9 @@ bool Compiler<Emitter>::visitDeclAndReturn(const VarDecl *VD, } template <class Emitter> -VarCreationState Compiler<Emitter>::visitVarDecl(const VarDecl *VD, - bool Toplevel, - bool IsConstexprUnknown) { +VarCreationState +Compiler<Emitter>::visitVarDecl(const VarDecl *VD, const Expr *Init, + bool Toplevel, bool IsConstexprUnknown) { // We don't know what to do with these, so just return false. if (VD->getType().isNull()) return false; @@ -4814,7 +4813,6 @@ VarCreationState Compiler<Emitter>::visitVarDecl(const VarDecl *VD, if (!this->isActive()) return VarCreationState::NotCreated(); - const Expr *Init = VD->getInit(); OptPrimType VarT = classify(VD->getType()); if (Init && Init->isValueDependent()) @@ -5488,7 +5486,8 @@ template <class Emitter> bool Compiler<Emitter>::maybeEmitDeferredVarInit(const VarDecl *VD) { if (auto *DD = dyn_cast_if_present<DecompositionDecl>(VD)) { for (auto *BD : DD->flat_bindings()) - if (auto *KD = BD->getHoldingVar(); KD && !this->visitVarDecl(KD)) + if (auto *KD = BD->getHoldingVar(); + KD && !this->visitVarDecl(KD, KD->getInit())) return false; } return true; @@ -5552,7 +5551,7 @@ bool Compiler<Emitter>::visitDeclStmt(const DeclStmt *DS, const auto *VD = dyn_cast<VarDecl>(D); if (!VD) return false; - if (!this->visitVarDecl(VD)) + if (!this->visitVarDecl(VD, VD->getInit())) return false; // Register decomposition decl holding vars. diff --git a/clang/lib/AST/ByteCode/Compiler.h b/clang/lib/AST/ByteCode/Compiler.h index c97dc18656ce4..5f392964c076a 100644 --- a/clang/lib/AST/ByteCode/Compiler.h +++ b/clang/lib/AST/ByteCode/Compiler.h @@ -251,7 +251,8 @@ class Compiler : public ConstStmtVisitor<Compiler<Emitter>, bool>, bool visitExpr(const Expr *E, bool DestroyToplevelScope) override; bool visitFunc(const FunctionDecl *F) override; - bool visitDeclAndReturn(const VarDecl *VD, bool ConstantContext) override; + bool visitDeclAndReturn(const VarDecl *VD, const Expr *Init, + bool ConstantContext) override; protected: /// Emits scope cleanup instructions. @@ -303,7 +304,8 @@ class Compiler : public ConstStmtVisitor<Compiler<Emitter>, bool>, /// intact. bool delegate(const Expr *E); /// Creates and initializes a variable from the given decl. - VarCreationState visitVarDecl(const VarDecl *VD, bool Toplevel = false, + VarCreationState visitVarDecl(const VarDecl *VD, const Expr *Init, + bool Toplevel = false, bool IsConstexprUnknown = false); VarCreationState visitDecl(const VarDecl *VD, bool IsConstexprUnknown = false); diff --git a/clang/lib/AST/ByteCode/Context.cpp b/clang/lib/AST/ByteCode/Context.cpp index 8598996681466..6e6c60925a70f 100644 --- a/clang/lib/AST/ByteCode/Context.cpp +++ b/clang/lib/AST/ByteCode/Context.cpp @@ -126,7 +126,7 @@ bool Context::evaluate(State &Parent, const Expr *E, APValue &Result, } bool Context::evaluateAsInitializer(State &Parent, const VarDecl *VD, - APValue &Result) { + const Expr *Init, APValue &Result) { ++EvalID; bool Recursing = !Stk.empty(); size_t StackSizeBefore = Stk.size(); @@ -135,7 +135,7 @@ bool Context::evaluateAsInitializer(State &Parent, const VarDecl *VD, bool CheckGlobalInitialized = shouldBeGloballyIndexed(VD) && (VD->getType()->isRecordType() || VD->getType()->isArrayType()); - auto Res = C.interpretDecl(VD, CheckGlobalInitialized); + auto Res = C.interpretDecl(VD, Init, CheckGlobalInitialized); if (Res.isInvalid()) { C.cleanup(); Stk.clearTo(StackSizeBefore); diff --git a/clang/lib/AST/ByteCode/Context.h b/clang/lib/AST/ByteCode/Context.h index fa98498dbe8fa..280a31725555f 100644 --- a/clang/lib/AST/ByteCode/Context.h +++ b/clang/lib/AST/ByteCode/Context.h @@ -59,7 +59,8 @@ class Context final { ConstantExprKind Kind); /// Evaluates a toplevel initializer. - bool evaluateAsInitializer(State &Parent, const VarDecl *VD, APValue &Result); + bool evaluateAsInitializer(State &Parent, const VarDecl *VD, const Expr *Init, + APValue &Result); bool evaluateCharRange(State &Parent, const Expr *SizeExpr, const Expr *PtrExpr, APValue &Result); diff --git a/clang/lib/AST/ByteCode/EvalEmitter.cpp b/clang/lib/AST/ByteCode/EvalEmitter.cpp index e349397078aa3..1d73f0e247aa2 100644 --- a/clang/lib/AST/ByteCode/EvalEmitter.cpp +++ b/clang/lib/AST/ByteCode/EvalEmitter.cpp @@ -49,14 +49,15 @@ EvaluationResult EvalEmitter::interpretExpr(const Expr *E, return std::move(this->EvalResult); } -EvaluationResult EvalEmitter::interpretDecl(const VarDecl *VD, +EvaluationResult EvalEmitter::interpretDecl(const VarDecl *VD, const Expr *Init, bool CheckFullyInitialized) { this->CheckFullyInitialized = CheckFullyInitialized; S.EvaluatingDecl = VD; S.setEvalLocation(VD->getLocation()); EvalResult.setSource(VD); - if (const Expr *Init = VD->getAnyInitializer()) { + // FIXME: I think Init is never null. + if (Init) { QualType T = VD->getType(); this->ConvertResultToRValue = !Init->isGLValue() && !T->isPointerType() && !T->isObjCObjectPointerType(); @@ -65,7 +66,7 @@ EvaluationResult EvalEmitter::interpretDecl(const VarDecl *VD, EvalResult.setSource(VD); - if (!this->visitDeclAndReturn(VD, S.inConstantContext())) + if (!this->visitDeclAndReturn(VD, Init, S.inConstantContext())) EvalResult.setInvalid(); S.EvaluatingDecl = nullptr; diff --git a/clang/lib/AST/ByteCode/EvalEmitter.h b/clang/lib/AST/ByteCode/EvalEmitter.h index 85a0a99fbb4b0..e81ea67adf97a 100644 --- a/clang/lib/AST/ByteCode/EvalEmitter.h +++ b/clang/lib/AST/ByteCode/EvalEmitter.h @@ -37,7 +37,8 @@ class EvalEmitter : public SourceMapper { EvaluationResult interpretExpr(const Expr *E, bool ConvertResultToRValue = false, bool DestroyToplevelScope = false); - EvaluationResult interpretDecl(const VarDecl *VD, bool CheckFullyInitialized); + EvaluationResult interpretDecl(const VarDecl *VD, const Expr *Init, + bool CheckFullyInitialized); /// Interpret the given Expr to a Pointer. EvaluationResult interpretAsPointer(const Expr *E, PtrCallback PtrCB); /// Interpret the given expression as if it was in the body of the given @@ -59,7 +60,8 @@ class EvalEmitter : public SourceMapper { /// Methods implemented by the compiler. virtual bool visitExpr(const Expr *E, bool DestroyToplevelScope) = 0; - virtual bool visitDeclAndReturn(const VarDecl *VD, bool ConstantContext) = 0; + virtual bool visitDeclAndReturn(const VarDecl *VD, const Expr *Init, + bool ConstantContext) = 0; virtual bool visitFunc(const FunctionDecl *F) = 0; virtual bool visit(const Expr *E) = 0; virtual bool emitBool(bool V, const Expr *E) = 0; diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 5145896930153..820b053057067 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -17755,7 +17755,7 @@ bool Expr::EvaluateAsInitializer(APValue &Value, const ASTContext &Ctx, if (Info.EnableNewConstInterp) { auto &InterpCtx = const_cast<ASTContext &>(Ctx).getInterpContext(); - if (!InterpCtx.evaluateAsInitializer(Info, VD, Value)) + if (!InterpCtx.evaluateAsInitializer(Info, VD, this, Value)) return false; return CheckConstantExpression(Info, DeclLoc, DeclTy, Value, diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 946b1e39af3b9..a72bdedd7317b 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -4393,6 +4393,13 @@ renderDebugOptions(const ToolChain &TC, const Driver &D, const llvm::Triple &T, // object file generation and no IR generation, -gN should not be needed. So // allow -gsplit-dwarf with either -gN or IR input. if (IRInput || Args.hasArg(options::OPT_g_Group)) { + // FIXME: -gsplit-dwarf on AIX is currently unimplemented. + if (TC.getTriple().isOSAIX() && Args.hasArg(options::OPT_gsplit_dwarf)) { + D.Diag(diag::err_drv_unsupported_opt_for_target) + << Args.getLastArg(options::OPT_gsplit_dwarf)->getSpelling() + << TC.getTriple().str(); + return; + } Arg *SplitDWARFArg; DwarfFission = getDebugFissionKind(D, Args, SplitDWARFArg); if (DwarfFission != DwarfFissionKind::None && diff --git a/clang/test/Driver/aix-gsplit-dwarf.c b/clang/test/Driver/aix-gsplit-dwarf.c new file mode 100644 index 0000000000000..22f2a66961f36 --- /dev/null +++ b/clang/test/Driver/aix-gsplit-dwarf.c @@ -0,0 +1,12 @@ +// Verify error message is emitted for `-gsplit-dwarf` on AIX +// as it's unsupported at the moment. + +// RUN: not %clang -target powerpc-ibm-aix -gdwarf-4 -gsplit-dwarf %s 2>&1 \ +// RUN: | FileCheck %s --check-prefix=UNSUP_OPT_AIX +// RUN: not %clang -target powerpc64-ibm-aix -gdwarf-4 -gsplit-dwarf %s 2>&1 \ +// RUN: | FileCheck %s --check-prefix=UNSUP_OPT_AIX64 + +// UNSUP_OPT_AIX: error: unsupported option '-gsplit-dwarf' for target 'powerpc-ibm-aix' +// UNSUP_OPT_AIX64: error: unsupported option '-gsplit-dwarf' for target 'powerpc64-ibm-aix' + +int main(){return 0;} diff --git a/clang/test/Modules/added-visible-decls.cppm b/clang/test/Modules/added-visible-decls.cppm index 2f387db452905..28df3bf6f8543 100644 --- a/clang/test/Modules/added-visible-decls.cppm +++ b/clang/test/Modules/added-visible-decls.cppm @@ -5,6 +5,7 @@ // RUN: %clang_cc1 -std=c++20 %t/b.cppm -emit-reduced-module-interface -o %t/b.pcm -fprebuilt-module-path=%t // RUN: %clang_cc1 -std=c++20 %t/c.cppm -emit-reduced-module-interface -o %t/c.pcm -fprebuilt-module-path=%t // RUN: %clang_cc1 -std=c++20 %t/d.cpp -fprebuilt-module-path=%t -fsyntax-only -verify +// RUN: %clang_cc1 -std=c++20 %t/d.cpp -fprebuilt-module-path=%t -fsyntax-only -verify -fexperimental-new-constant-interpreter //--- a.h template <typename T> _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits