RIscRIpt created this revision. Herald added a subscriber: pengfei. Herald added a project: All. RIscRIpt requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
Consider the following code: #include <windows.h> #include <TraceLoggingActivity.h> #include <TraceLoggingProvider.h> #include <winmeta.h> TRACELOGGING_DEFINE_PROVIDER( g_hMyComponentProvider, "SimpleTraceLoggingProvider", // {0205c616-cf97-5c11-9756-56a2cee02ca7} (0x0205c616,0xcf97,0x5c11,0x97,0x56,0x56,0xa2,0xce,0xe0,0x2c,0xa7)); void test() { TraceLoggingFunction(g_hMyComponentProvider); } int main() { TraceLoggingRegister(g_hMyComponentProvider); test(); TraceLoggingUnregister(g_hMyComponentProvider); } It compiles with MSVC, but clang-cl reports an error: C:\Program Files (x86)\Windows Kits\10\\include\10.0.22621.0\\shared/TraceLoggingActivity.h(377,30): note: expanded from macro '_tlgThisFunctionName' #define _tlgThisFunctionName __FUNCTION__ ^ .\tl.cpp(14,5): error: cannot initialize an array element of type 'char' with an lvalue of type 'const char[5]' TraceLoggingFunction(g_hMyComponentProvider); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The second commit is not needed to support above code, however, during isolated tests in ms_predefined_expr.cpp I found that MSVC accepts code with constexpr, whereas clang-cl does not. I see that in most places PredefinedExpr is supported in constant evaluation, so I didn't wrap my code with ``if(MicrosoftExt)``. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D158591 Files: clang/lib/AST/ExprConstant.cpp clang/lib/Sema/Sema.cpp clang/test/Sema/ms_predefined_expr.cpp Index: clang/test/Sema/ms_predefined_expr.cpp =================================================================== --- clang/test/Sema/ms_predefined_expr.cpp +++ clang/test/Sema/ms_predefined_expr.cpp @@ -168,3 +168,40 @@ void test_char_injection(decltype(sizeof('"')), decltype(sizeof("()"))) { unused("" __FUNCSIG__); // expected-warning{{expansion of predefined identifier '__FUNCSIG__' to a string literal is a Microsoft extension}} } + +void test_in_struct_init() { + struct { + char F[sizeof(__FUNCTION__)]; + } s1 = { __FUNCTION__ }; // expected-warning{{initializing an array from a '__FUNCTION__' predefined identifier is a Microsoft extension}} + + struct { + char F[sizeof("F:" __FUNCTION__)]; // expected-warning{{expansion of predefined identifier '__FUNCTION__' to a string literal is a Microsoft extension}} + } s2 = { "F:" __FUNCTION__ }; // expected-warning{{expansion of predefined identifier '__FUNCTION__' to a string literal is a Microsoft extension}} + + class C { + public: + struct { + char F[sizeof(__FUNCTION__)]; + } s; + } c1 = { { __FUNCTION__ } }; // expected-warning{{initializing an array from a '__FUNCTION__' predefined identifier is a Microsoft extension}} +} + +void test_in_constexpr_struct_init() { + struct { + char F[sizeof(__FUNCTION__)]; + } constexpr s1 = { __FUNCTION__ }; // expected-warning{{initializing an array from a '__FUNCTION__' predefined identifier is a Microsoft extension}} + ASSERT_EQ(__FUNCTION__, s1.F); + + struct { + char F[sizeof("F:" __FUNCTION__)]; // expected-warning{{expansion of predefined identifier '__FUNCTION__' to a string literal is a Microsoft extension}} + } constexpr s2 = { "F:" __FUNCTION__ }; // expected-warning{{expansion of predefined identifier '__FUNCTION__' to a string literal is a Microsoft extension}} + ASSERT_EQ("F:" __FUNCTION__, s2.F); // expected-warning{{expansion of predefined identifier '__FUNCTION__' to a string literal is a Microsoft extension}} + + class C { + public: + struct { + char F[sizeof("F:" __FUNCTION__)]; // expected-warning{{expansion of predefined identifier '__FUNCTION__' to a string literal is a Microsoft extension}} + } s; + } constexpr c1 = { { "F:" __FUNCTION__ } }; // expected-warning{{expansion of predefined identifier '__FUNCTION__' to a string literal is a Microsoft extension}} + ASSERT_EQ("F:" __FUNCTION__, c1.s.F); // expected-warning{{expansion of predefined identifier '__FUNCTION__' to a string literal is a Microsoft extension}} +} Index: clang/lib/Sema/Sema.cpp =================================================================== --- clang/lib/Sema/Sema.cpp +++ clang/lib/Sema/Sema.cpp @@ -1492,15 +1492,11 @@ } Decl *Sema::getCurLocalScopeDecl() { - if (const BlockScopeInfo *BSI = getCurBlock()) - return BSI->TheDecl; - if (const LambdaScopeInfo *LSI = getCurLambda()) - return LSI->CallOperator; - if (const CapturedRegionScopeInfo *CSI = getCurCapturedRegion()) - return CSI->TheCapturedDecl; - if (NamedDecl *ND = getCurFunctionOrMethodDecl()) - return ND; - return nullptr; + DeclContext *DC = CurContext; + while (DC && !isa<BlockDecl>(DC) && !isa<CapturedDecl>(DC) && + !isa<FunctionDecl>(DC) && !isa<ObjCMethodDecl>(DC)) + DC = DC->getParent(); + return dyn_cast_or_null<Decl>(DC); } LangAS Sema::getDefaultCXXMethodAddrSpace() const { Index: clang/lib/AST/ExprConstant.cpp =================================================================== --- clang/lib/AST/ExprConstant.cpp +++ clang/lib/AST/ExprConstant.cpp @@ -7524,6 +7524,9 @@ return Error(E); } + bool VisitPredefinedExpr(const PredefinedExpr *E) { + return StmtVisitorTy::Visit(E->getFunctionName()); + } bool VisitConstantExpr(const ConstantExpr *E) { if (E->hasAPValueResult()) return DerivedSuccess(E->getAPValueResult(), E);
Index: clang/test/Sema/ms_predefined_expr.cpp =================================================================== --- clang/test/Sema/ms_predefined_expr.cpp +++ clang/test/Sema/ms_predefined_expr.cpp @@ -168,3 +168,40 @@ void test_char_injection(decltype(sizeof('"')), decltype(sizeof("()"))) { unused("" __FUNCSIG__); // expected-warning{{expansion of predefined identifier '__FUNCSIG__' to a string literal is a Microsoft extension}} } + +void test_in_struct_init() { + struct { + char F[sizeof(__FUNCTION__)]; + } s1 = { __FUNCTION__ }; // expected-warning{{initializing an array from a '__FUNCTION__' predefined identifier is a Microsoft extension}} + + struct { + char F[sizeof("F:" __FUNCTION__)]; // expected-warning{{expansion of predefined identifier '__FUNCTION__' to a string literal is a Microsoft extension}} + } s2 = { "F:" __FUNCTION__ }; // expected-warning{{expansion of predefined identifier '__FUNCTION__' to a string literal is a Microsoft extension}} + + class C { + public: + struct { + char F[sizeof(__FUNCTION__)]; + } s; + } c1 = { { __FUNCTION__ } }; // expected-warning{{initializing an array from a '__FUNCTION__' predefined identifier is a Microsoft extension}} +} + +void test_in_constexpr_struct_init() { + struct { + char F[sizeof(__FUNCTION__)]; + } constexpr s1 = { __FUNCTION__ }; // expected-warning{{initializing an array from a '__FUNCTION__' predefined identifier is a Microsoft extension}} + ASSERT_EQ(__FUNCTION__, s1.F); + + struct { + char F[sizeof("F:" __FUNCTION__)]; // expected-warning{{expansion of predefined identifier '__FUNCTION__' to a string literal is a Microsoft extension}} + } constexpr s2 = { "F:" __FUNCTION__ }; // expected-warning{{expansion of predefined identifier '__FUNCTION__' to a string literal is a Microsoft extension}} + ASSERT_EQ("F:" __FUNCTION__, s2.F); // expected-warning{{expansion of predefined identifier '__FUNCTION__' to a string literal is a Microsoft extension}} + + class C { + public: + struct { + char F[sizeof("F:" __FUNCTION__)]; // expected-warning{{expansion of predefined identifier '__FUNCTION__' to a string literal is a Microsoft extension}} + } s; + } constexpr c1 = { { "F:" __FUNCTION__ } }; // expected-warning{{expansion of predefined identifier '__FUNCTION__' to a string literal is a Microsoft extension}} + ASSERT_EQ("F:" __FUNCTION__, c1.s.F); // expected-warning{{expansion of predefined identifier '__FUNCTION__' to a string literal is a Microsoft extension}} +} Index: clang/lib/Sema/Sema.cpp =================================================================== --- clang/lib/Sema/Sema.cpp +++ clang/lib/Sema/Sema.cpp @@ -1492,15 +1492,11 @@ } Decl *Sema::getCurLocalScopeDecl() { - if (const BlockScopeInfo *BSI = getCurBlock()) - return BSI->TheDecl; - if (const LambdaScopeInfo *LSI = getCurLambda()) - return LSI->CallOperator; - if (const CapturedRegionScopeInfo *CSI = getCurCapturedRegion()) - return CSI->TheCapturedDecl; - if (NamedDecl *ND = getCurFunctionOrMethodDecl()) - return ND; - return nullptr; + DeclContext *DC = CurContext; + while (DC && !isa<BlockDecl>(DC) && !isa<CapturedDecl>(DC) && + !isa<FunctionDecl>(DC) && !isa<ObjCMethodDecl>(DC)) + DC = DC->getParent(); + return dyn_cast_or_null<Decl>(DC); } LangAS Sema::getDefaultCXXMethodAddrSpace() const { Index: clang/lib/AST/ExprConstant.cpp =================================================================== --- clang/lib/AST/ExprConstant.cpp +++ clang/lib/AST/ExprConstant.cpp @@ -7524,6 +7524,9 @@ return Error(E); } + bool VisitPredefinedExpr(const PredefinedExpr *E) { + return StmtVisitorTy::Visit(E->getFunctionName()); + } bool VisitConstantExpr(const ConstantExpr *E) { if (E->hasAPValueResult()) return DerivedSuccess(E->getAPValueResult(), E);
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits