llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang-codegen Author: Boaz Brickner (bricknerb) <details> <summary>Changes</summary> This happens when using `-O2`. Added a test that reproduces it based on a test that was reverted in #<!-- -->111701: https://github.com/bricknerb/llvm-project/blob/93e4a7386ec897e53d7330c6206d38759a858be2/clang/test/CodeGen/deeply-nested-expressions.cpp However, this test is slow and likely to be hard to maintained as discussed in https://github.com/llvm/llvm-project/pull/111701/files/1a63281b6c240352653fd2e4299755c1f32a76f4#r1795518779 so unless there are objections I plan to remove this test before merging. --- Full diff: https://github.com/llvm/llvm-project/pull/124128.diff 4 Files Affected: - (modified) clang/lib/CodeGen/CodeGenFunction.cpp (+1-1) - (modified) clang/lib/CodeGen/VarBypassDetector.cpp (+14-9) - (modified) clang/lib/CodeGen/VarBypassDetector.h (+6-3) - (added) clang/test/CodeGen/deeply-nested-expressions.cpp (+30) ``````````diff diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index 11fdddba1144bb..6bdfbbd4013039 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -1533,7 +1533,7 @@ void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn, // Initialize helper which will detect jumps which can cause invalid // lifetime markers. if (ShouldEmitLifetimeMarkers) - Bypasses.Init(Body); + Bypasses.Init(CGM, Body); } // Emit the standard function prologue. diff --git a/clang/lib/CodeGen/VarBypassDetector.cpp b/clang/lib/CodeGen/VarBypassDetector.cpp index 6eda83dfdef2f3..7b2b3542928ad7 100644 --- a/clang/lib/CodeGen/VarBypassDetector.cpp +++ b/clang/lib/CodeGen/VarBypassDetector.cpp @@ -8,6 +8,7 @@ #include "VarBypassDetector.h" +#include "CodeGenModule.h" #include "clang/AST/Decl.h" #include "clang/AST/Expr.h" #include "clang/AST/Stmt.h" @@ -17,13 +18,13 @@ using namespace CodeGen; /// Clear the object and pre-process for the given statement, usually function /// body statement. -void VarBypassDetector::Init(const Stmt *Body) { +void VarBypassDetector::Init(CodeGenModule &CGM, const Stmt *Body) { FromScopes.clear(); ToScopes.clear(); Bypasses.clear(); Scopes = {{~0U, nullptr}}; unsigned ParentScope = 0; - AlwaysBypassed = !BuildScopeInformation(Body, ParentScope); + AlwaysBypassed = !BuildScopeInformation(CGM, Body, ParentScope); if (!AlwaysBypassed) Detect(); } @@ -31,7 +32,7 @@ void VarBypassDetector::Init(const Stmt *Body) { /// Build scope information for a declaration that is part of a DeclStmt. /// Returns false if we failed to build scope information and can't tell for /// which vars are being bypassed. -bool VarBypassDetector::BuildScopeInformation(const Decl *D, +bool VarBypassDetector::BuildScopeInformation(CodeGenModule &CGM, const Decl *D, unsigned &ParentScope) { const VarDecl *VD = dyn_cast<VarDecl>(D); if (VD && VD->hasLocalStorage()) { @@ -41,7 +42,7 @@ bool VarBypassDetector::BuildScopeInformation(const Decl *D, if (const VarDecl *VD = dyn_cast<VarDecl>(D)) if (const Expr *Init = VD->getInit()) - return BuildScopeInformation(Init, ParentScope); + return BuildScopeInformation(CGM, Init, ParentScope); return true; } @@ -50,7 +51,7 @@ bool VarBypassDetector::BuildScopeInformation(const Decl *D, /// LabelAndGotoScopes and recursively walking the AST as needed. /// Returns false if we failed to build scope information and can't tell for /// which vars are being bypassed. -bool VarBypassDetector::BuildScopeInformation(const Stmt *S, +bool VarBypassDetector::BuildScopeInformation(CodeGenModule &CGM, const Stmt *S, unsigned &origParentScope) { // If this is a statement, rather than an expression, scopes within it don't // propagate out into the enclosing scope. Otherwise we have to worry about @@ -68,12 +69,12 @@ bool VarBypassDetector::BuildScopeInformation(const Stmt *S, case Stmt::SwitchStmtClass: if (const Stmt *Init = cast<SwitchStmt>(S)->getInit()) { - if (!BuildScopeInformation(Init, ParentScope)) + if (!BuildScopeInformation(CGM, Init, ParentScope)) return false; ++StmtsToSkip; } if (const VarDecl *Var = cast<SwitchStmt>(S)->getConditionVariable()) { - if (!BuildScopeInformation(Var, ParentScope)) + if (!BuildScopeInformation(CGM, Var, ParentScope)) return false; ++StmtsToSkip; } @@ -86,7 +87,7 @@ bool VarBypassDetector::BuildScopeInformation(const Stmt *S, case Stmt::DeclStmtClass: { const DeclStmt *DS = cast<DeclStmt>(S); for (auto *I : DS->decls()) - if (!BuildScopeInformation(I, origParentScope)) + if (!BuildScopeInformation(CGM, I, origParentScope)) return false; return true; } @@ -126,7 +127,11 @@ bool VarBypassDetector::BuildScopeInformation(const Stmt *S, } // Recursively walk the AST. - if (!BuildScopeInformation(SubStmt, ParentScope)) + bool Result; + CGM.runWithSufficientStackSpace(S->getEndLoc(), [&] { + Result = BuildScopeInformation(CGM, SubStmt, ParentScope); + }); + if (!Result) return false; } return true; diff --git a/clang/lib/CodeGen/VarBypassDetector.h b/clang/lib/CodeGen/VarBypassDetector.h index 164e88c0b2f1b2..cc4d387aeaa5ba 100644 --- a/clang/lib/CodeGen/VarBypassDetector.h +++ b/clang/lib/CodeGen/VarBypassDetector.h @@ -14,6 +14,7 @@ #ifndef LLVM_CLANG_LIB_CODEGEN_VARBYPASSDETECTOR_H #define LLVM_CLANG_LIB_CODEGEN_VARBYPASSDETECTOR_H +#include "CodeGenModule.h" #include "clang/AST/Decl.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseSet.h" @@ -50,7 +51,7 @@ class VarBypassDetector { bool AlwaysBypassed = false; public: - void Init(const Stmt *Body); + void Init(CodeGenModule &CGM, const Stmt *Body); /// Returns true if the variable declaration was by bypassed by any goto or /// switch statement. @@ -59,8 +60,10 @@ class VarBypassDetector { } private: - bool BuildScopeInformation(const Decl *D, unsigned &ParentScope); - bool BuildScopeInformation(const Stmt *S, unsigned &origParentScope); + bool BuildScopeInformation(CodeGenModule &CGM, const Decl *D, + unsigned &ParentScope); + bool BuildScopeInformation(CodeGenModule &CGM, const Stmt *S, + unsigned &origParentScope); void Detect(); void Detect(unsigned From, unsigned To); }; diff --git a/clang/test/CodeGen/deeply-nested-expressions.cpp b/clang/test/CodeGen/deeply-nested-expressions.cpp new file mode 100644 index 00000000000000..98980be7506481 --- /dev/null +++ b/clang/test/CodeGen/deeply-nested-expressions.cpp @@ -0,0 +1,30 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - -Wstack-exhausted +// RUN: %clang_cc1 %s -emit-llvm -o - -Wstack-exhausted -O2 + +class AClass { +public: + AClass() {} + AClass &f() { return *this; } +}; + +#define CALLS1 f +#define CALLS2 CALLS1().CALLS1 +#define CALLS4 CALLS2().CALLS2 +#define CALLS8 CALLS4().CALLS4 +#define CALLS16 CALLS8().CALLS8 +#define CALLS32 CALLS16().CALLS16 +#define CALLS64 CALLS32().CALLS32 +#define CALLS128 CALLS64().CALLS64 +#define CALLS256 CALLS128().CALLS128 +#define CALLS512 CALLS256().CALLS256 +#define CALLS1024 CALLS512().CALLS512 +#define CALLS2048 CALLS1024().CALLS1024 +#define CALLS4096 CALLS2048().CALLS2048 +#define CALLS8192 CALLS4096().CALLS4096 +#define CALLS16384 CALLS8192().CALLS8192 +#define CALLS32768 CALLS16384().CALLS16384 + +void test_bar() { + AClass a; + a.CALLS32768(); +} `````````` </details> https://github.com/llvm/llvm-project/pull/124128 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits