thakis created this revision. clang-cl sets MicrosoftCompat. In that mode, we always give enums a fixed underlying type, and for enums with fixed underlying type we never enter the block that tries to emit ext_ms_forward_ref_enum. Fix this by requiring an explicit underlying type when we're skipping this diagnostic.
We had a test for this warning, but it only ran in C++98 mode. clang-cl always enables -std=c++14, so MicrosoftCompatibiliy-cxx98.cpp is a fairly useless test. Fold it into MicrosoftCompatibility.cpp -- that way, the test checks if -Wmicrosoft-enum-forward-reference can fire in clang-cl builds. https://reviews.llvm.org/D32369 Files: lib/Sema/SemaDecl.cpp test/SemaCXX/MicrosoftCompatibility-cxx98.cpp test/SemaCXX/MicrosoftCompatibility.cpp Index: test/SemaCXX/MicrosoftCompatibility.cpp =================================================================== --- test/SemaCXX/MicrosoftCompatibility.cpp +++ test/SemaCXX/MicrosoftCompatibility.cpp @@ -224,6 +224,15 @@ } +//MSVC allows forward enum declaration +enum ENUM; // expected-warning {{forward references to 'enum' types are a Microsoft extension}} +ENUM *var = 0; +ENUM var2 = (ENUM)3; +enum ENUM1* var3 = 0;// expected-warning {{forward references to 'enum' types are a Microsoft extension}} + +enum ENUM1 { kA }; +enum ENUM1; // This way round is fine. + enum ENUM2 { ENUM2_a = (enum ENUM2) 4, ENUM2_b = 0x9FFFFFFF, // expected-warning {{enumerator value is not representable in the underlying type 'int'}} @@ -269,3 +278,18 @@ f(0xffffffffffffffffi64); } } + +typedef void (*FnPtrTy)(); +void (*PR23733_1)() = static_cast<FnPtrTy>((void *)0); // expected-warning {{static_cast between pointer-to-function and pointer-to-object is a Microsoft extension}} +void (*PR23733_2)() = FnPtrTy((void *)0); +void (*PR23733_3)() = (FnPtrTy)((void *)0); +void (*PR23733_4)() = reinterpret_cast<FnPtrTy>((void *)0); + +long function_prototype(int a); +long (*function_ptr)(int a); + +void function_to_voidptr_conv() { + void *a1 = function_prototype; // expected-warning {{implicit conversion between pointer-to-function and pointer-to-object is a Microsoft extension}} + void *a2 = &function_prototype; // expected-warning {{implicit conversion between pointer-to-function and pointer-to-object is a Microsoft extension}} + void *a3 = function_ptr; // expected-warning {{implicit conversion between pointer-to-function and pointer-to-object is a Microsoft extension}} +} Index: test/SemaCXX/MicrosoftCompatibility-cxx98.cpp =================================================================== --- test/SemaCXX/MicrosoftCompatibility-cxx98.cpp +++ test/SemaCXX/MicrosoftCompatibility-cxx98.cpp @@ -1,23 +0,0 @@ -// RUN: %clang_cc1 %s -triple i686-pc-win32 -fsyntax-only -std=c++98 -Wmicrosoft -verify -fms-compatibility -fexceptions -fcxx-exceptions - - -//MSVC allows forward enum declaration -enum ENUM; // expected-warning {{forward references to 'enum' types are a Microsoft extension}} -ENUM *var = 0; -ENUM var2 = (ENUM)3; -enum ENUM1* var3 = 0;// expected-warning {{forward references to 'enum' types are a Microsoft extension}} - -typedef void (*FnPtrTy)(); -void (*PR23733_1)() = static_cast<FnPtrTy>((void *)0); // expected-warning {{static_cast between pointer-to-function and pointer-to-object is a Microsoft extension}} -void (*PR23733_2)() = FnPtrTy((void *)0); -void (*PR23733_3)() = (FnPtrTy)((void *)0); -void (*PR23733_4)() = reinterpret_cast<FnPtrTy>((void *)0); - -long function_prototype(int a); -long (*function_ptr)(int a); - -void function_to_voidptr_conv() { - void *a1 = function_prototype; // expected-warning {{implicit conversion between pointer-to-function and pointer-to-object is a Microsoft extension}} - void *a2 = &function_prototype; // expected-warning {{implicit conversion between pointer-to-function and pointer-to-object is a Microsoft extension}} - void *a3 = function_ptr; // expected-warning {{implicit conversion between pointer-to-function and pointer-to-object is a Microsoft extension}} -} Index: lib/Sema/SemaDecl.cpp =================================================================== --- lib/Sema/SemaDecl.cpp +++ lib/Sema/SemaDecl.cpp @@ -13523,7 +13523,8 @@ // If this is an undefined enum, warn. if (TUK != TUK_Definition && !Invalid) { TagDecl *Def; - if ((getLangOpts().CPlusPlus11 || getLangOpts().ObjC2) && + if (!EnumUnderlyingIsImplicit && + (getLangOpts().CPlusPlus11 || getLangOpts().ObjC2) && cast<EnumDecl>(New)->isFixed()) { // C++0x: 7.2p2: opaque-enum-declaration. // Conflicts are diagnosed above. Do nothing.
Index: test/SemaCXX/MicrosoftCompatibility.cpp =================================================================== --- test/SemaCXX/MicrosoftCompatibility.cpp +++ test/SemaCXX/MicrosoftCompatibility.cpp @@ -224,6 +224,15 @@ } +//MSVC allows forward enum declaration +enum ENUM; // expected-warning {{forward references to 'enum' types are a Microsoft extension}} +ENUM *var = 0; +ENUM var2 = (ENUM)3; +enum ENUM1* var3 = 0;// expected-warning {{forward references to 'enum' types are a Microsoft extension}} + +enum ENUM1 { kA }; +enum ENUM1; // This way round is fine. + enum ENUM2 { ENUM2_a = (enum ENUM2) 4, ENUM2_b = 0x9FFFFFFF, // expected-warning {{enumerator value is not representable in the underlying type 'int'}} @@ -269,3 +278,18 @@ f(0xffffffffffffffffi64); } } + +typedef void (*FnPtrTy)(); +void (*PR23733_1)() = static_cast<FnPtrTy>((void *)0); // expected-warning {{static_cast between pointer-to-function and pointer-to-object is a Microsoft extension}} +void (*PR23733_2)() = FnPtrTy((void *)0); +void (*PR23733_3)() = (FnPtrTy)((void *)0); +void (*PR23733_4)() = reinterpret_cast<FnPtrTy>((void *)0); + +long function_prototype(int a); +long (*function_ptr)(int a); + +void function_to_voidptr_conv() { + void *a1 = function_prototype; // expected-warning {{implicit conversion between pointer-to-function and pointer-to-object is a Microsoft extension}} + void *a2 = &function_prototype; // expected-warning {{implicit conversion between pointer-to-function and pointer-to-object is a Microsoft extension}} + void *a3 = function_ptr; // expected-warning {{implicit conversion between pointer-to-function and pointer-to-object is a Microsoft extension}} +} Index: test/SemaCXX/MicrosoftCompatibility-cxx98.cpp =================================================================== --- test/SemaCXX/MicrosoftCompatibility-cxx98.cpp +++ test/SemaCXX/MicrosoftCompatibility-cxx98.cpp @@ -1,23 +0,0 @@ -// RUN: %clang_cc1 %s -triple i686-pc-win32 -fsyntax-only -std=c++98 -Wmicrosoft -verify -fms-compatibility -fexceptions -fcxx-exceptions - - -//MSVC allows forward enum declaration -enum ENUM; // expected-warning {{forward references to 'enum' types are a Microsoft extension}} -ENUM *var = 0; -ENUM var2 = (ENUM)3; -enum ENUM1* var3 = 0;// expected-warning {{forward references to 'enum' types are a Microsoft extension}} - -typedef void (*FnPtrTy)(); -void (*PR23733_1)() = static_cast<FnPtrTy>((void *)0); // expected-warning {{static_cast between pointer-to-function and pointer-to-object is a Microsoft extension}} -void (*PR23733_2)() = FnPtrTy((void *)0); -void (*PR23733_3)() = (FnPtrTy)((void *)0); -void (*PR23733_4)() = reinterpret_cast<FnPtrTy>((void *)0); - -long function_prototype(int a); -long (*function_ptr)(int a); - -void function_to_voidptr_conv() { - void *a1 = function_prototype; // expected-warning {{implicit conversion between pointer-to-function and pointer-to-object is a Microsoft extension}} - void *a2 = &function_prototype; // expected-warning {{implicit conversion between pointer-to-function and pointer-to-object is a Microsoft extension}} - void *a3 = function_ptr; // expected-warning {{implicit conversion between pointer-to-function and pointer-to-object is a Microsoft extension}} -} Index: lib/Sema/SemaDecl.cpp =================================================================== --- lib/Sema/SemaDecl.cpp +++ lib/Sema/SemaDecl.cpp @@ -13523,7 +13523,8 @@ // If this is an undefined enum, warn. if (TUK != TUK_Definition && !Invalid) { TagDecl *Def; - if ((getLangOpts().CPlusPlus11 || getLangOpts().ObjC2) && + if (!EnumUnderlyingIsImplicit && + (getLangOpts().CPlusPlus11 || getLangOpts().ObjC2) && cast<EnumDecl>(New)->isFixed()) { // C++0x: 7.2p2: opaque-enum-declaration. // Conflicts are diagnosed above. Do nothing.
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits