red1bluelost created this revision. red1bluelost added reviewers: rsmith, lebedev.ri, aaron.ballman. Herald added a project: All. red1bluelost requested review of this revision. Herald added a project: clang.
Ensures an -Wenum-conversion warning happens when one of the enums is signed and the other is unsigned. Also adds a test file to verify these warnings. This warning would not happen since the -Wsign-conversion would make a diagnostic then return, never allowing the -Wenum-conversion checks. For example: C enum PE { P = -1 }; enum NE { N }; enum NE conv(enum PE E) { return E; } Before this would only create a diagnostic with -Wsign-conversion and never on -Wenum-conversion. Now it will create a diagnostic for both -Wsign-conversion and -Wenum-conversion. I could change it to just warn on -Wenum-conversion as that was what I initially did. Seeing PR35200 (or GitHub Issue 316268), I let both diagnostics check so that the sign conversion could generate a warning. This was tested with `check-clang` and all tests passed along with the new test file. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D123009 Files: clang/lib/Sema/SemaChecking.cpp clang/test/Sema/enum-enum-conversion.c Index: clang/test/Sema/enum-enum-conversion.c =================================================================== --- /dev/null +++ clang/test/Sema/enum-enum-conversion.c @@ -0,0 +1,39 @@ +// RUN: %clang_cc1 -triple=x86_64-pc-linux-gnu -fsyntax-only -verify -Wenum-conversion -DENUM_CONV %s +// RUN: %clang_cc1 -triple=x86_64-pc-linux-gnu -fsyntax-only -verify -Wconversion %s + +enum NE1 { N1 = -1 }; +enum NE2 { N2 = -2 }; +enum PE1 { P1 }; +enum PE2 { P2 }; + +enum PE2 f1(enum PE1 E) { +#ifdef ENUM_CONV + return E; // expected-warning {{implicit conversion from enumeration type 'enum PE1' to different enumeration type 'enum PE2'}} +#else + return E; // expected-warning {{implicit conversion from enumeration type 'enum PE1' to different enumeration type 'enum PE2'}} +#endif +} + +enum NE1 f2(enum PE1 E) { +#ifdef ENUM_CONV + return E; // expected-warning {{implicit conversion from enumeration type 'enum PE1' to different enumeration type 'enum NE1'}} +#else + return E; // expected-warning {{implicit conversion from enumeration type 'enum PE1' to different enumeration type 'enum NE1'}} expected-warning {{implicit conversion changes signedness: 'enum PE1' to 'enum NE1'}} +#endif +} + +enum PE1 f3(enum NE1 E) { +#ifdef ENUM_CONV + return E; // expected-warning {{implicit conversion from enumeration type 'enum NE1' to different enumeration type 'enum PE1'}} +#else + return E; // expected-warning {{implicit conversion from enumeration type 'enum NE1' to different enumeration type 'enum PE1'}} expected-warning {{implicit conversion changes signedness: 'enum NE1' to 'enum PE1'}} +#endif +} + +enum NE2 f4(enum NE1 E) { +#ifdef ENUM_CONV + return E; // expected-warning {{implicit conversion from enumeration type 'enum NE1' to different enumeration type 'enum NE2'}} +#else + return E; // expected-warning {{implicit conversion from enumeration type 'enum NE1' to different enumeration type 'enum NE2'}} +#endif +} \ No newline at end of file Index: clang/lib/Sema/SemaChecking.cpp =================================================================== --- clang/lib/Sema/SemaChecking.cpp +++ clang/lib/Sema/SemaChecking.cpp @@ -13552,7 +13552,9 @@ *ICContext = true; } - return DiagnoseImpCast(S, E, T, CC, DiagID); + DiagnoseImpCast(S, E, T, CC, DiagID); + if (!isa<EnumType>(Target) || !isa<EnumType>(Source)) + return; } // Diagnose conversions between different enumeration types.
Index: clang/test/Sema/enum-enum-conversion.c =================================================================== --- /dev/null +++ clang/test/Sema/enum-enum-conversion.c @@ -0,0 +1,39 @@ +// RUN: %clang_cc1 -triple=x86_64-pc-linux-gnu -fsyntax-only -verify -Wenum-conversion -DENUM_CONV %s +// RUN: %clang_cc1 -triple=x86_64-pc-linux-gnu -fsyntax-only -verify -Wconversion %s + +enum NE1 { N1 = -1 }; +enum NE2 { N2 = -2 }; +enum PE1 { P1 }; +enum PE2 { P2 }; + +enum PE2 f1(enum PE1 E) { +#ifdef ENUM_CONV + return E; // expected-warning {{implicit conversion from enumeration type 'enum PE1' to different enumeration type 'enum PE2'}} +#else + return E; // expected-warning {{implicit conversion from enumeration type 'enum PE1' to different enumeration type 'enum PE2'}} +#endif +} + +enum NE1 f2(enum PE1 E) { +#ifdef ENUM_CONV + return E; // expected-warning {{implicit conversion from enumeration type 'enum PE1' to different enumeration type 'enum NE1'}} +#else + return E; // expected-warning {{implicit conversion from enumeration type 'enum PE1' to different enumeration type 'enum NE1'}} expected-warning {{implicit conversion changes signedness: 'enum PE1' to 'enum NE1'}} +#endif +} + +enum PE1 f3(enum NE1 E) { +#ifdef ENUM_CONV + return E; // expected-warning {{implicit conversion from enumeration type 'enum NE1' to different enumeration type 'enum PE1'}} +#else + return E; // expected-warning {{implicit conversion from enumeration type 'enum NE1' to different enumeration type 'enum PE1'}} expected-warning {{implicit conversion changes signedness: 'enum NE1' to 'enum PE1'}} +#endif +} + +enum NE2 f4(enum NE1 E) { +#ifdef ENUM_CONV + return E; // expected-warning {{implicit conversion from enumeration type 'enum NE1' to different enumeration type 'enum NE2'}} +#else + return E; // expected-warning {{implicit conversion from enumeration type 'enum NE1' to different enumeration type 'enum NE2'}} +#endif +} \ No newline at end of file Index: clang/lib/Sema/SemaChecking.cpp =================================================================== --- clang/lib/Sema/SemaChecking.cpp +++ clang/lib/Sema/SemaChecking.cpp @@ -13552,7 +13552,9 @@ *ICContext = true; } - return DiagnoseImpCast(S, E, T, CC, DiagID); + DiagnoseImpCast(S, E, T, CC, DiagID); + if (!isa<EnumType>(Target) || !isa<EnumType>(Source)) + return; } // Diagnose conversions between different enumeration types.
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits