From e8e387ccfb5c43aa585c24fd2b05a4e64dae9fee Mon Sep 17 00:00:00 2001 From: luofeng14 Date: Mon, 18 Nov 2024 20:35:59 +0800 Subject: [PATCH] [clang] allow global initializers to use non-constant static --- clang/lib/Sema/SemaExpr.cpp | 15 +++++++++++--- ...-constant-global-initializers-disabled.cpp | 9 +++++++++ .../non-constant-global-initializers.cpp | 20 +++++++++++++++++++ 3 files changed, 41 insertions(+), 3 deletions(-) create mode 100644 clang/test/SemaCXX/non-constant-global-initializers-disabled.cpp create mode 100644 clang/test/SemaCXX/non-constant-global-initializers.cpp diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 3a5e302cc03a..e2d7d18508a8 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -7729,9 +7729,18 @@ Sema::BuildCompoundLiteralExpr(SourceLocation LParenLoc, TypeSourceInfo *TInfo, if (isFileScope) { if (!LiteralExpr->isTypeDependent() && !LiteralExpr->isValueDependent() && - !literalType->isDependentType()) // C99 6.5.2.5p3 - if (CheckForConstantInitializer(LiteralExpr, literalType)) - return ExprError(); + !literalType->isDependentType()) { + #ifdef BUILD_FOR_OPENEULER + // Try to behave like gcc and ignore this check by default + // while compiling CPP files. + bool ignoreCheck = getLangOpts().CPlusPlus && + getLangOpts().GccCompatible; + if (!ignoreCheck && CheckForConstantInitializer(LiteralExpr, literalType)) + #else + if (CheckForConstantInitializer(LiteralExpr, literalType)) + #endif + return ExprError(); + } } else if (literalType.getAddressSpace() != LangAS::opencl_private && literalType.getAddressSpace() != LangAS::Default) { // Embedded-C extensions to C99 6.5.2.5: diff --git a/clang/test/SemaCXX/non-constant-global-initializers-disabled.cpp b/clang/test/SemaCXX/non-constant-global-initializers-disabled.cpp new file mode 100644 index 000000000000..bcd75c6aca82 --- /dev/null +++ b/clang/test/SemaCXX/non-constant-global-initializers-disabled.cpp @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -x c -fsyntax-only %s -verify +// RUN: %clang_cc1 -x c++ -fsyntax-only %s -verify + +int* f(int *); +struct DT { int * el;}; +int * pa = 0; +struct DT va = (struct DT){pa}; // expected-error {{initializer element is not a compile-time constant}} +struct DT vb = (struct DT){pa + 1}; // expected-error {{initializer element is not a compile-time constant}} +struct DT vc = (struct DT){f(pa) + 1}; // expected-error {{initializer element is not a compile-time constant}} diff --git a/clang/test/SemaCXX/non-constant-global-initializers.cpp b/clang/test/SemaCXX/non-constant-global-initializers.cpp new file mode 100644 index 000000000000..b968c5c29455 --- /dev/null +++ b/clang/test/SemaCXX/non-constant-global-initializers.cpp @@ -0,0 +1,20 @@ +// The first and second runs check that nothing has been changed for C +// RUN: not %clang_cc1 -x c -fsyntax-only %s 2> %t +// RUN: FileCheck %s < %t +// RUN: not %clang_cc1 -x c -fsyntax-only -fgcc-compatible %s 2> %t +// RUN: FileCheck %s < %t + +// The third and fourth runs check that it works for C++ both by default and by enabling the option +// RUN: not %clang_cc1 -x c++ -fsyntax-only %s +// RUN: %clang_cc1 -x c++ -fsyntax-only -fgcc-compatible %s +// expected-no-diagnostics + +int* f(int *); +struct DT { int * el;}; +int * pa = 0; +struct DT va = (struct DT){pa}; +// CHECK:[[@LINE-1]]:28: error: initializer element is not a compile-time constant +struct DT vb = (struct DT){pa + 1}; +// CHECK:[[@LINE-1]]:31: error: initializer element is not a compile-time constant +struct DT vc = (struct DT){f(pa) + 1}; +// CHECK:[[@LINE-1]]:34: error: initializer element is not a compile-time constant -- Gitee