Index: clang/include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- clang/include/clang/Basic/DiagnosticSemaKinds.td +++ clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -3477,6 +3477,9 @@ "cast to %1 from smaller integer type %0">, InGroup; +def note_reduce_expression_chaining : Note< + "Reduce the number of chained expressions, using helper variables or parens">; + def warn_attribute_ignored_for_field_of_type : Warning< "%0 attribute ignored for field of type %1">, InGroup; Index: clang/lib/Sema/SemaChecking.cpp =================================================================== --- clang/lib/Sema/SemaChecking.cpp +++ clang/lib/Sema/SemaChecking.cpp @@ -10368,8 +10368,10 @@ IsSameFloatAfterCast(value.getComplexFloatImag(), Src, Tgt)); } -static void AnalyzeImplicitConversions(Sema &S, Expr *E, SourceLocation CC, - bool IsListInit = false); +static void +AnalyzeImplicitConversions(Sema &S, Expr *E, SourceLocation CC, + bool IsListInit = false, + bool CalledWithSufficientStackSpace = false); static bool IsEnumConstOrFromMacro(Sema &S, Expr *E) { // Suppress cases where we are comparing against an enum constant. @@ -11927,8 +11929,21 @@ /// AnalyzeImplicitConversions - Find and report any interesting /// implicit conversions in the given expression. There are a couple /// of competing diagnostics here, -Wconversion and -Wsign-compare. -static void AnalyzeImplicitConversions(Sema &S, Expr *OrigE, SourceLocation CC, - bool IsListInit/*= false*/) { +/// +/// \param CalledWithSufficientStackSpace is the function called from +/// \ref Sema::runWithSufficientStackSpace if not it calls itself as lamba to +/// that function. +static void +AnalyzeImplicitConversions(Sema &S, Expr *OrigE, SourceLocation CC, + bool IsListInit /*= false*/, + bool CalledWithSufficientStackSpace /*= false*/) { + if (!CalledWithSufficientStackSpace) { + S.runWithSufficientStackSpace( + CC, [&] { AnalyzeImplicitConversions(S, OrigE, CC, IsListInit, true); }, + diag::note_reduce_expression_chaining); + return; + } + QualType T = OrigE->getType(); Expr *E = OrigE->IgnoreParenImpCasts(); Index: clang/test/Sema/stack-overflow-expr-bool.cpp =================================================================== --- /dev/null +++ clang/test/Sema/stack-overflow-expr-bool.cpp @@ -0,0 +1,21 @@ +// The segmentation fault gives exit code 139 +// RUN: not not %clang_cc1 %s -fsyntax-only 2>&1 | FileCheck %s +// REQUIRES: thread_support + +#define A10 ARG ARG ARG ARG ARG ARG ARG ARG ARG ARG +#define A100 A10 A10 A10 A10 A10 A10 A10 A10 A10 A10 +#define A1000 A10 A10 A10 A10 A10 A10 A10 A10 A10 A10 +#define A10000 A100 A100 A100 A100 A100 A100 A100 A100 A100 A100 +#define A100000 A1000 A1000 A1000 A1000 A1000 A1000 A1000 A1000 A1000 A1000 +#define A1000000 A10000 A10000 A10000 A10000 A10000 A10000 A10000 A10000 A10000 A10000 +#define A10000000 A100000 A100000 A100000 A100000 A100000 A100000 A100000 A100000 A100000 A100000 +#define A100000000 A1000000 A1000000 A1000000 A1000000 A1000000 A1000000 A1000000 A1000000 A1000000 A1000000 + +#define ARG true && +void foo() { + bool b = A100000000 true; +} + +// CHECK: warning: stack nearly exhausted; compilation time may suffer, and crashes due to stack overflow are likely +// CHECK: note: Reduce the number of chained expressions, using helper variables or parens +// CHECK: Stack dump: Index: clang/test/Sema/stack-overflow-expr-double.c =================================================================== --- /dev/null +++ clang/test/Sema/stack-overflow-expr-double.c @@ -0,0 +1,21 @@ +// The segmentation fault gives exit code 139 +// RUN: not not %clang_cc1 %s -fsyntax-only 2>&1 | FileCheck %s +// REQUIRES: thread_support + +#define A10 ARG ARG ARG ARG ARG ARG ARG ARG ARG ARG +#define A100 A10 A10 A10 A10 A10 A10 A10 A10 A10 A10 +#define A1000 A10 A10 A10 A10 A10 A10 A10 A10 A10 A10 +#define A10000 A100 A100 A100 A100 A100 A100 A100 A100 A100 A100 +#define A100000 A1000 A1000 A1000 A1000 A1000 A1000 A1000 A1000 A1000 A1000 +#define A1000000 A10000 A10000 A10000 A10000 A10000 A10000 A10000 A10000 A10000 A10000 +#define A10000000 A100000 A100000 A100000 A100000 A100000 A100000 A100000 A100000 A100000 A100000 +#define A100000000 A1000000 A1000000 A1000000 A1000000 A1000000 A1000000 A1000000 A1000000 A1000000 A1000000 + +#define ARG 1. + +void foo() { + double f = A100000000 1.; +} + +// CHECK: warning: stack nearly exhausted; compilation time may suffer, and crashes due to stack overflow are likely +// CHECK: note: Reduce the number of chained expressions, using helper variables or parens +// CHECK: Stack dump: Index: clang/test/Sema/stack-overflow-expr-int.c =================================================================== --- /dev/null +++ clang/test/Sema/stack-overflow-expr-int.c @@ -0,0 +1,21 @@ +// The segmentation fault gives exit code 139 +// RUN: not not %clang_cc1 %s -fsyntax-only 2>&1 | FileCheck %s +// REQUIRES: thread_support + +#define A10 ARG ARG ARG ARG ARG ARG ARG ARG ARG ARG +#define A100 A10 A10 A10 A10 A10 A10 A10 A10 A10 A10 +#define A1000 A10 A10 A10 A10 A10 A10 A10 A10 A10 A10 +#define A10000 A100 A100 A100 A100 A100 A100 A100 A100 A100 A100 +#define A100000 A1000 A1000 A1000 A1000 A1000 A1000 A1000 A1000 A1000 A1000 +#define A1000000 A10000 A10000 A10000 A10000 A10000 A10000 A10000 A10000 A10000 A10000 +#define A10000000 A100000 A100000 A100000 A100000 A100000 A100000 A100000 A100000 A100000 A100000 +#define A100000000 A1000000 A1000000 A1000000 A1000000 A1000000 A1000000 A1000000 A1000000 A1000000 A1000000 + +#define ARG 1 + +void foo() { + int i = A100000000 1; +} + +// CHECK: warning: stack nearly exhausted; compilation time may suffer, and crashes due to stack overflow are likely +// CHECK: note: Reduce the number of chained expressions, using helper variables or parens +// CHECK: Stack dump: