efriedma updated this revision to Diff 413989. efriedma added a comment. Added warning. This roughly matches the corresponding MSVC warning, as far as I can tell.
Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D120936/new/ https://reviews.llvm.org/D120936 Files: clang/include/clang/Basic/DiagnosticSemaKinds.td clang/lib/Sema/SemaExprCXX.cpp clang/lib/Sema/SemaOverload.cpp clang/test/SemaCXX/MicrosoftExtensions.cpp
Index: clang/test/SemaCXX/MicrosoftExtensions.cpp =================================================================== --- clang/test/SemaCXX/MicrosoftExtensions.cpp +++ clang/test/SemaCXX/MicrosoftExtensions.cpp @@ -85,18 +85,22 @@ foo_unaligned(p2); __unaligned B_unaligned *p3 = 0; - int p4 = foo_unaligned(p3); + int p4 = foo_unaligned(p3); // expected-error {{cannot initialize a variable of type 'int' with an rvalue of type 'void *'}} + // expected-warning@-1 {{implicit cast from type '__unaligned B_unaligned *' to type 'B_unaligned *' drops __unaligned qualifier}} - B_unaligned *p5 = p3; // expected-error {{cannot initialize a variable of type 'B_unaligned *' with an lvalue of type '__unaligned B_unaligned *'}} + B_unaligned *p5 = p3; + // expected-warning@-1 {{implicit cast from type '__unaligned B_unaligned *' to type 'B_unaligned *' drops __unaligned qualifier}} __unaligned B_unaligned *p6 = p3; p1_aligned_type4 = p2_aligned_type4; - p2_aligned_type4 = p1_aligned_type4; // expected-error {{assigning to 'int aligned_type4::*' from incompatible type '__unaligned int aligned_type4::*'}} + p2_aligned_type4 = p1_aligned_type4; + // expected-warning@-1 {{implicit cast from type '__unaligned int aligned_type4::*' to type 'int aligned_type4::*' drops __unaligned qualifier}} p3_aligned_type4 = p1_aligned_type4; __unaligned int a[10]; - int *b = a; // expected-error {{cannot initialize a variable of type 'int *' with an lvalue of type '__unaligned int[10]'}} + int *b = a; + // expected-warning@-1 {{implicit cast from type '__unaligned int[10]' to type 'int *' drops __unaligned qualifier}} } // Test from PR27367 @@ -115,13 +119,18 @@ // We should accept type conversion of __unaligned to non-__unaligned references typedef struct in_addr { public: - in_addr(in_addr &a) {} // expected-note {{candidate constructor not viable: no known conversion from '__unaligned IN_ADDR *' (aka '__unaligned in_addr *') to 'in_addr &' for 1st argument; dereference the argument with *}} - in_addr(in_addr *a) {} // expected-note {{candidate constructor not viable: 1st argument ('__unaligned IN_ADDR *' (aka '__unaligned in_addr *')) would lose __unaligned qualifier}} + in_addr(in_addr &a) {} // expected-note {{candidate constructor not viable: expects an lvalue for 1st argument}} + in_addr(in_addr *a) {} // expected-note {{candidate constructor not viable: no known conversion from 'IN_ADDR' (aka 'in_addr') to 'in_addr *' for 1st argument}} } IN_ADDR; void f(IN_ADDR __unaligned *a) { IN_ADDR local_addr = *a; - IN_ADDR local_addr2 = a; // expected-error {{no viable conversion from '__unaligned IN_ADDR *' (aka '__unaligned in_addr *') to 'IN_ADDR' (aka 'in_addr')}} + // FIXME: MSVC accepts the following; not sure why clang tries to + // copy-construct an in_addr. + IN_ADDR local_addr2 = a; // expected-error {{no viable constructor copying variable of type 'IN_ADDR' (aka 'in_addr')}} + // expected-warning@-1 {{implicit cast from type '__unaligned IN_ADDR *' (aka '__unaligned in_addr *') to type 'in_addr *' drops __unaligned qualifier}} + IN_ADDR local_addr3(a); + // expected-warning@-1 {{implicit cast from type '__unaligned IN_ADDR *' (aka '__unaligned in_addr *') to type 'in_addr *' drops __unaligned qualifier}} } template<typename T> void h1(T (__stdcall M::* const )()) { } Index: clang/lib/Sema/SemaOverload.cpp =================================================================== --- clang/lib/Sema/SemaOverload.cpp +++ clang/lib/Sema/SemaOverload.cpp @@ -3195,9 +3195,8 @@ Qualifiers FromQuals = FromType.getQualifiers(); Qualifiers ToQuals = ToType.getQualifiers(); - // Ignore __unaligned qualifier if this type is void. - if (ToType.getUnqualifiedType()->isVoidType()) - FromQuals.removeUnaligned(); + // Ignore __unaligned qualifier. + FromQuals.removeUnaligned(); // Objective-C ARC: // Check Objective-C lifetime conversions. Index: clang/lib/Sema/SemaExprCXX.cpp =================================================================== --- clang/lib/Sema/SemaExprCXX.cpp +++ clang/lib/Sema/SemaExprCXX.cpp @@ -4641,6 +4641,13 @@ From->getType()->getPointeeType().getAddressSpace()) CK = CK_AddressSpaceConversion; + if (!isCast(CCK) && + !ToType->getPointeeType().getQualifiers().hasUnaligned() && + From->getType()->getPointeeType().getQualifiers().hasUnaligned()) { + Diag(From->getBeginLoc(), diag::warn_imp_cast_drops_unaligned) + << InitialFromType << ToType; + } + From = ImpCastExprToType(From, ToType.getNonLValueExprType(Context), CK, VK, /*BasePath=*/nullptr, CCK) .get(); Index: clang/include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- clang/include/clang/Basic/DiagnosticSemaKinds.td +++ clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -10271,6 +10271,11 @@ def warn_mig_server_routine_does_not_return_kern_return_t : Warning< "'mig_server_routine' attribute only applies to routines that return a kern_return_t">, InGroup<IgnoredAttributes>; + +def warn_imp_cast_drops_unaligned : Warning< + "implicit cast from type %0 to type %1 drops __unaligned qualifier">, + InGroup<DiagGroup<"unaligned-qualifier-implicit-cast">>; + } // end of sema category let CategoryName = "OpenMP Issue" in {
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits