forked from OSchip/llvm-project
[Sema][Windows] Don't special-case void* in __unaligned conversions.
As far as I can tell, MSVC allows the relevant conversions for all pointer types. Found compiling a Windows SDK header. I've verified that the updated errors in MicrosoftExtensions.cpp match the ones that MSVC actually emits, except for the one with a FIXME. (Not sure why this wasn't done for the patch that added the tests.) To make up for the missing error, add a warning that triggers on conversions that drop the __unaligned qualfier. Differential Revision: https://reviews.llvm.org/D120936
This commit is contained in:
parent
f71f9958b9
commit
27a5749625
|
@ -10272,6 +10272,11 @@ def err_openclcxx_placement_new : Error<
|
|||
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 {
|
||||
|
|
|
@ -4641,6 +4641,13 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType,
|
|||
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();
|
||||
|
|
|
@ -3195,9 +3195,8 @@ static bool isQualificationConversionStep(QualType FromType, QualType ToType,
|
|||
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.
|
||||
|
|
|
@ -85,18 +85,22 @@ void test_unaligned() {
|
|||
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 @@ __inline void FreeIDListArray(LPITEMIDLIST *ppidls) {
|
|||
// 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 )()) { }
|
||||
|
|
Loading…
Reference in New Issue