diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 3a5e302cc03a319116a623e3b2d88148655cfa79..e2d7d18508a85a2069cf184367f18e4cbdf2c47f 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 0000000000000000000000000000000000000000..bcd75c6aca82e17789ab89a9fb17a118d1573c57 --- /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 0000000000000000000000000000000000000000..b968c5c29455ca3511f3b64323f50d65e395b80a --- /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