r343892 - Emit CK_NoOp casts in C mode, not just C++.

James Y Knight via cfe-commits cfe-commits at lists.llvm.org
Fri Oct 5 14:53:52 PDT 2018


Author: jyknight
Date: Fri Oct  5 14:53:51 2018
New Revision: 343892

URL: http://llvm.org/viewvc/llvm-project?rev=343892&view=rev
Log:
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

Added:
    cfe/trunk/test/Sema/c-casts.c
Modified:
    cfe/trunk/lib/AST/ExprConstant.cpp
    cfe/trunk/lib/Sema/SemaExpr.cpp

Modified: cfe/trunk/lib/AST/ExprConstant.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=343892&r1=343891&r2=343892&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ExprConstant.cpp (original)
+++ cfe/trunk/lib/AST/ExprConstant.cpp Fri Oct  5 14:53:51 2018
@@ -5864,11 +5864,7 @@ bool PointerExprEvaluator::VisitCastExpr
     // 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();

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=343892&r1=343891&r2=343892&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Fri Oct  5 14:53:51 2018
@@ -5862,6 +5862,8 @@ CastKind Sema::PrepareScalarCast(ExprRes
       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(QualTyp
     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);
     }
 

Added: cfe/trunk/test/Sema/c-casts.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/c-casts.c?rev=343892&view=auto
==============================================================================
--- cfe/trunk/test/Sema/c-casts.c (added)
+++ cfe/trunk/test/Sema/c-casts.c Fri Oct  5 14:53:51 2018
@@ -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;
+}




More information about the cfe-commits mailing list