Skip to content

Commit 49bf370

Browse files
committed
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
1 parent dc97118 commit 49bf370

File tree

3 files changed

+34
-6
lines changed

3 files changed

+34
-6
lines changed

clang/lib/AST/ExprConstant.cpp

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5864,11 +5864,7 @@ bool PointerExprEvaluator::VisitCastExpr(const CastExpr *E) {
58645864
// permitted in constant expressions in C++11. Bitcasts from cv void* are
58655865
// also static_casts, but we disallow them as a resolution to DR1312.
58665866
if (!E->getType()->isVoidPointerType()) {
5867-
// If we changed anything other than cvr-qualifiers, we can't use this
5868-
// value for constant folding. FIXME: Qualification conversions should
5869-
// always be CK_NoOp, but we get this wrong in C.
5870-
if (!Info.Ctx.hasCvrSimilarType(E->getType(), E->getSubExpr()->getType()))
5871-
Result.Designator.setInvalid();
5867+
Result.Designator.setInvalid();
58725868
if (SubExpr->getType()->isVoidPointerType())
58735869
CCEDiag(E, diag::note_constexpr_invalid_cast)
58745870
<< 3 << SubExpr->getType();

clang/lib/Sema/SemaExpr.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5862,6 +5862,8 @@ CastKind Sema::PrepareScalarCast(ExprResult &Src, QualType DestTy) {
58625862
LangAS DestAS = DestTy->getPointeeType().getAddressSpace();
58635863
if (SrcAS != DestAS)
58645864
return CK_AddressSpaceConversion;
5865+
if (Context.hasCvrSimilarType(SrcTy, DestTy))
5866+
return CK_NoOp;
58655867
return CK_BitCast;
58665868
}
58675869
case Type::STK_BlockPointer:
@@ -7762,7 +7764,12 @@ Sema::CheckAssignmentConstraints(QualType LHSType, ExprResult &RHS,
77627764
if (isa<PointerType>(RHSType)) {
77637765
LangAS AddrSpaceL = LHSPointer->getPointeeType().getAddressSpace();
77647766
LangAS AddrSpaceR = RHSType->getPointeeType().getAddressSpace();
7765-
Kind = AddrSpaceL != AddrSpaceR ? CK_AddressSpaceConversion : CK_BitCast;
7767+
if (AddrSpaceL != AddrSpaceR)
7768+
Kind = CK_AddressSpaceConversion;
7769+
else if (Context.hasCvrSimilarType(RHSType, LHSType))
7770+
Kind = CK_NoOp;
7771+
else
7772+
Kind = CK_BitCast;
77667773
return checkPointerTypesForAssignment(*this, LHSType, RHSType);
77677774
}
77687775

clang/test/Sema/c-casts.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// RUN: %clang_cc1 -w -ast-dump %s | FileCheck %s
2+
3+
// The cast construction code both for implicit and c-style casts is very
4+
// different in C vs C++. This file is intended to test the C behavior.
5+
6+
// TODO: add tests covering the rest of the code in
7+
// Sema::CheckAssignmentConstraints and Sema::PrepareScalarCast
8+
9+
// CHECK-LABEL: FunctionDecl {{.*}} cast_cvr_pointer
10+
void cast_cvr_pointer(char volatile * __restrict * const * p) {
11+
char*** x;
12+
// CHECK: ImplicitCastExpr {{.*}} 'char ***' <NoOp>
13+
x = p;
14+
// CHECK: CStyleCastExpr {{.*}} 'char ***' <NoOp>
15+
x = (char***)p;
16+
}
17+
18+
// CHECK-LABEL: FunctionDecl {{.*}} cast_pointer_type
19+
void cast_pointer_type(char *p) {
20+
void *x;
21+
// CHECK: ImplicitCastExpr {{.*}} 'void *' <BitCast>
22+
x = p;
23+
// CHECK: CStyleCastExpr {{.*}} 'void *' <BitCast>
24+
x = (void*)p;
25+
}

0 commit comments

Comments
 (0)