Emit CK_NoOp casts in C mode, not just C++.
Previously, it had been using CK_BitCast even for casts that only change const/restrict/volatile. Now it will use CK_Noop where appropriate. This is an alternate solution to r336746. Differential Revision: https://reviews.llvm.org/D52918 llvm-svn: 343892
This commit is contained in:
parent
dc97118efe
commit
49bf370a8b
|
@ -5864,11 +5864,7 @@ bool PointerExprEvaluator::VisitCastExpr(const CastExpr *E) {
|
|||
// permitted in constant expressions in C++11. Bitcasts from cv void* are
|
||||
// also static_casts, but we disallow them as a resolution to DR1312.
|
||||
if (!E->getType()->isVoidPointerType()) {
|
||||
// If we changed anything other than cvr-qualifiers, we can't use this
|
||||
// value for constant folding. FIXME: Qualification conversions should
|
||||
// always be CK_NoOp, but we get this wrong in C.
|
||||
if (!Info.Ctx.hasCvrSimilarType(E->getType(), E->getSubExpr()->getType()))
|
||||
Result.Designator.setInvalid();
|
||||
Result.Designator.setInvalid();
|
||||
if (SubExpr->getType()->isVoidPointerType())
|
||||
CCEDiag(E, diag::note_constexpr_invalid_cast)
|
||||
<< 3 << SubExpr->getType();
|
||||
|
|
|
@ -5862,6 +5862,8 @@ CastKind Sema::PrepareScalarCast(ExprResult &Src, QualType DestTy) {
|
|||
LangAS DestAS = DestTy->getPointeeType().getAddressSpace();
|
||||
if (SrcAS != DestAS)
|
||||
return CK_AddressSpaceConversion;
|
||||
if (Context.hasCvrSimilarType(SrcTy, DestTy))
|
||||
return CK_NoOp;
|
||||
return CK_BitCast;
|
||||
}
|
||||
case Type::STK_BlockPointer:
|
||||
|
@ -7762,7 +7764,12 @@ Sema::CheckAssignmentConstraints(QualType LHSType, ExprResult &RHS,
|
|||
if (isa<PointerType>(RHSType)) {
|
||||
LangAS AddrSpaceL = LHSPointer->getPointeeType().getAddressSpace();
|
||||
LangAS AddrSpaceR = RHSType->getPointeeType().getAddressSpace();
|
||||
Kind = AddrSpaceL != AddrSpaceR ? CK_AddressSpaceConversion : CK_BitCast;
|
||||
if (AddrSpaceL != AddrSpaceR)
|
||||
Kind = CK_AddressSpaceConversion;
|
||||
else if (Context.hasCvrSimilarType(RHSType, LHSType))
|
||||
Kind = CK_NoOp;
|
||||
else
|
||||
Kind = CK_BitCast;
|
||||
return checkPointerTypesForAssignment(*this, LHSType, RHSType);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
// RUN: %clang_cc1 -w -ast-dump %s | FileCheck %s
|
||||
|
||||
// The cast construction code both for implicit and c-style casts is very
|
||||
// different in C vs C++. This file is intended to test the C behavior.
|
||||
|
||||
// TODO: add tests covering the rest of the code in
|
||||
// Sema::CheckAssignmentConstraints and Sema::PrepareScalarCast
|
||||
|
||||
// CHECK-LABEL: FunctionDecl {{.*}} cast_cvr_pointer
|
||||
void cast_cvr_pointer(char volatile * __restrict * const * p) {
|
||||
char*** x;
|
||||
// CHECK: ImplicitCastExpr {{.*}} 'char ***' <NoOp>
|
||||
x = p;
|
||||
// CHECK: CStyleCastExpr {{.*}} 'char ***' <NoOp>
|
||||
x = (char***)p;
|
||||
}
|
||||
|
||||
// CHECK-LABEL: FunctionDecl {{.*}} cast_pointer_type
|
||||
void cast_pointer_type(char *p) {
|
||||
void *x;
|
||||
// CHECK: ImplicitCastExpr {{.*}} 'void *' <BitCast>
|
||||
x = p;
|
||||
// CHECK: CStyleCastExpr {{.*}} 'void *' <BitCast>
|
||||
x = (void*)p;
|
||||
}
|
Loading…
Reference in New Issue