mirror of https://github.com/microsoft/clang.git
[Sema] Mark implicitly-inserted ICE's as being part of explicit cast (PR38166)
Summary: As discussed in [[ https://bugs.llvm.org/show_bug.cgi?id=38166 | PR38166 ]], we need to be able to distinqush whether the cast we are visiting is actually a cast, or part of an `ExplicitCast`. There are at least four ways to get there: 1. Introduce a new `CastKind`, and use it instead of `IntegralCast` if we are in `ExplicitCast`. Would work, but does not scale - what if we will need more of these cast kinds? 2. Introduce a flag in `CastExprBits`, whether this cast is part of `ExplicitCast` or not. Would work, but it isn't immediately clear where it needs to be set. 2. Fix `ScalarExprEmitter::VisitCastExpr()` to visit these `NoOp` casts. As pointed out by @rsmith, CodeGenFunction::EmitMaterializeTemporaryExpr calls skipRValueSubobjectAdjustments, which steps over the CK_NoOp cast`, which explains why we currently don't visit those. This is probably impossible, as @efriedma points out, that is intentional as per `[class.temporary]` in the standard 3. And the simplest one, just record which NoOp casts we skip. It just kinda works as-is afterwards. But, the approach with a flag is the least intrusive one, and is probably the best one overall. Reviewers: rsmith, rjmccall, majnemer, efriedma Reviewed By: rsmith Subscribers: cfe-commits, aaron.ballman, vsk, llvm-commits, rsmith Differential Revision: https://reviews.llvm.org/D49508 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@337815 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
8bc411272b
commit
03e3fc09a8
|
@ -2821,6 +2821,7 @@ protected:
|
|||
(op && op->containsUnexpandedParameterPack()))),
|
||||
Op(op) {
|
||||
CastExprBits.Kind = kind;
|
||||
CastExprBits.PartOfExplicitCast = false;
|
||||
setBasePathSize(BasePathSize);
|
||||
assert(CastConsistency());
|
||||
}
|
||||
|
@ -2835,6 +2836,13 @@ public:
|
|||
CastKind getCastKind() const { return (CastKind) CastExprBits.Kind; }
|
||||
void setCastKind(CastKind K) { CastExprBits.Kind = K; }
|
||||
|
||||
bool getIsPartOfExplicitCast() const {
|
||||
return CastExprBits.PartOfExplicitCast;
|
||||
}
|
||||
void setIsPartOfExplicitCast(bool PartOfExplicitCast) {
|
||||
CastExprBits.PartOfExplicitCast = PartOfExplicitCast;
|
||||
}
|
||||
|
||||
static const char *getCastKindName(CastKind CK);
|
||||
const char *getCastKindName() const { return getCastKindName(getCastKind()); }
|
||||
|
||||
|
|
|
@ -202,7 +202,8 @@ protected:
|
|||
unsigned : NumExprBits;
|
||||
|
||||
unsigned Kind : 6;
|
||||
unsigned BasePathSize : 32 - 6 - NumExprBits;
|
||||
unsigned PartOfExplicitCast : 1;
|
||||
unsigned BasePathSize : 32 - 6 - 1 - NumExprBits;
|
||||
};
|
||||
|
||||
class CallExprBitfields {
|
||||
|
|
|
@ -2117,6 +2117,9 @@ void ASTDumper::VisitCastExpr(const CastExpr *Node) {
|
|||
}
|
||||
dumpBasePath(OS, Node);
|
||||
OS << ">";
|
||||
|
||||
if (Node->getIsPartOfExplicitCast())
|
||||
OS << " part_of_explicit_cast";
|
||||
}
|
||||
|
||||
void ASTDumper::VisitDeclRefExpr(const DeclRefExpr *Node) {
|
||||
|
|
|
@ -89,6 +89,14 @@ namespace {
|
|||
void CheckCXXCStyleCast(bool FunctionalCast, bool ListInitialization);
|
||||
void CheckCStyleCast();
|
||||
|
||||
void updatePartOfExplicitCastFlags(CastExpr *CE) {
|
||||
// Walk down from the CE to the OrigSrcExpr, and mark all immediate
|
||||
// ImplicitCastExpr's as being part of ExplicitCastExpr. The original CE
|
||||
// (which is a ExplicitCastExpr), and the OrigSrcExpr are not touched.
|
||||
while ((CE = dyn_cast<ImplicitCastExpr>(CE->getSubExpr())))
|
||||
CE->setIsPartOfExplicitCast(true);
|
||||
}
|
||||
|
||||
/// Complete an apparently-successful cast operation that yields
|
||||
/// the given expression.
|
||||
ExprResult complete(CastExpr *castExpr) {
|
||||
|
@ -100,6 +108,7 @@ namespace {
|
|||
CK_Dependent, castExpr, nullptr,
|
||||
castExpr->getValueKind());
|
||||
}
|
||||
updatePartOfExplicitCastFlags(castExpr);
|
||||
return castExpr;
|
||||
}
|
||||
|
||||
|
|
|
@ -723,6 +723,7 @@ void ASTStmtReader::VisitCastExpr(CastExpr *E) {
|
|||
assert(NumBaseSpecs == E->path_size());
|
||||
E->setSubExpr(Record.readSubExpr());
|
||||
E->setCastKind((CastKind)Record.readInt());
|
||||
E->setIsPartOfExplicitCast(Record.readInt());
|
||||
CastExpr::path_iterator BaseI = E->path_begin();
|
||||
while (NumBaseSpecs--) {
|
||||
auto *BaseSpec = new (Record.getContext()) CXXBaseSpecifier;
|
||||
|
|
|
@ -2192,6 +2192,7 @@ void ASTWriter::WriteDeclAbbrevs() {
|
|||
// CastExpr
|
||||
Abv->Add(BitCodeAbbrevOp(0)); // PathSize
|
||||
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 6)); // CastKind
|
||||
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // PartOfExplicitCast
|
||||
// ImplicitCastExpr
|
||||
ExprImplicitCastAbbrev = Stream.EmitAbbrev(std::move(Abv));
|
||||
|
||||
|
|
|
@ -665,6 +665,7 @@ void ASTStmtWriter::VisitCastExpr(CastExpr *E) {
|
|||
Record.push_back(E->path_size());
|
||||
Record.AddStmt(E->getSubExpr());
|
||||
Record.push_back(E->getCastKind()); // FIXME: stable encoding
|
||||
Record.push_back(E->getIsPartOfExplicitCast());
|
||||
|
||||
for (CastExpr::path_iterator
|
||||
PI = E->path_begin(), PE = E->path_end(); PI != PE; ++PI)
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
// Test this without pch.
|
||||
// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -include %S/cxx_exprs.h -std=c++11 -fsyntax-only -verify %s -ast-dump
|
||||
// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -include %S/cxx_exprs.h -std=c++11 -fsyntax-only -verify %s -ast-dump | FileCheck %s
|
||||
|
||||
// Test with pch. Use '-ast-dump' to force deserialization of function bodies.
|
||||
// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -x c++-header -std=c++11 -emit-pch -o %t %S/cxx_exprs.h
|
||||
// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-dump
|
||||
// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-dump-all | FileCheck %s
|
||||
|
||||
// expected-no-diagnostics
|
||||
|
||||
|
@ -14,19 +14,49 @@ bool boolean;
|
|||
|
||||
// CXXStaticCastExpr
|
||||
static_cast_result void_ptr = &integer;
|
||||
// CHECK: TypedefDecl {{.*}} <{{.*}}, col:{{.*}}> col:{{.*}}{{(imported)?}} referenced static_cast_result 'typeof (static_cast<void *>(0))':'void *'{{$}}
|
||||
// CHECK-NEXT: TypeOfExprType {{.*}} 'typeof (static_cast<void *>(0))' sugar{{( imported)?}}{{$}}
|
||||
// CHECK-NEXT: ParenExpr {{.*}} <col:{{.*}}, col:{{.*}}> 'void *'{{$}}
|
||||
// CHECK-NEXT: CXXStaticCastExpr {{.*}} <col:{{.*}}, col:{{.*}}> 'void *' static_cast<void *> <NoOp>{{$}}
|
||||
// CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'void *' <NullToPointer> part_of_explicit_cast{{$}}
|
||||
// CHECK-NEXT: IntegerLiteral {{.*}} <col:{{.*}}> 'int' 0{{$}}
|
||||
|
||||
// CXXDynamicCastExpr
|
||||
Derived *d;
|
||||
dynamic_cast_result derived_ptr = d;
|
||||
// CHECK: TypedefDecl {{.*}} <{{.*}}, col:{{.*}}> col:{{.*}} referenced dynamic_cast_result 'typeof (dynamic_cast<Derived *>(base_ptr))':'Derived *'{{$}}
|
||||
// CHECK-NEXT: TypeOfExprType {{.*}} 'typeof (dynamic_cast<Derived *>(base_ptr))' sugar{{( imported)?}}{{$}}
|
||||
// CHECK-NEXT: ParenExpr {{.*}} <col:{{.*}}, col:{{.*}}> 'Derived *'{{$}}
|
||||
// CHECK-NEXT: CXXDynamicCastExpr {{.*}} <col:{{.*}}, col:{{.*}}> 'Derived *' dynamic_cast<struct Derived *> <Dynamic>{{$}}
|
||||
// CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'Base *' <LValueToRValue> part_of_explicit_cast{{$}}
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} <col:{{.*}}> 'Base *' lvalue Var {{.*}} 'base_ptr' 'Base *'{{$}}
|
||||
|
||||
// CXXReinterpretCastExpr
|
||||
reinterpret_cast_result void_ptr2 = &integer;
|
||||
// CHECK: TypedefDecl {{.*}} <{{.*}}, col:{{.*}}> col:{{.*}} referenced reinterpret_cast_result 'typeof (reinterpret_cast<void *>(0))':'void *'{{$}}
|
||||
// CHECK-NEXT: TypeOfExprType {{.*}} 'typeof (reinterpret_cast<void *>(0))' sugar{{( imported)?}}{{$}}
|
||||
// CHECK-NEXT: ParenExpr {{.*}} <col:{{.*}}, col:{{.*}}> 'void *'{{$}}
|
||||
// CHECK-NEXT: CXXReinterpretCastExpr {{.*}} <col:{{.*}}, col:{{.*}}> 'void *' reinterpret_cast<void *> <IntegralToPointer>{{$}}
|
||||
// CHECK-NEXT: IntegerLiteral {{.*}} <col:{{.*}}> 'int' 0{{$}}
|
||||
|
||||
// CXXConstCastExpr
|
||||
const_cast_result char_ptr = &character;
|
||||
// CHECK: TypedefDecl {{.*}} <{{.*}}, col:{{.*}}> col:{{.*}} referenced const_cast_result 'typeof (const_cast<char *>(const_char_ptr_value))':'char *'{{$}}
|
||||
// CHECK-NEXT: TypeOfExprType {{.*}} 'typeof (const_cast<char *>(const_char_ptr_value))' sugar{{( imported)?}}{{$}}
|
||||
// CHECK-NEXT: ParenExpr {{.*}} <col:{{.*}}, col:{{.*}}> 'char *'{{$}}
|
||||
// CHECK-NEXT: CXXConstCastExpr {{.*}} <col:{{.*}}, col:{{.*}}> 'char *' const_cast<char *> <NoOp>{{$}}
|
||||
// CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'const char *' <LValueToRValue> part_of_explicit_cast{{$}}
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} <col:{{.*}}> 'const char *' lvalue Var {{.*}} 'const_char_ptr_value' 'const char *'{{$}}
|
||||
|
||||
// CXXFunctionalCastExpr
|
||||
functional_cast_result *double_ptr = &floating;
|
||||
// CHECK: TypedefDecl {{.*}} <{{.*}}, col:{{.*}}> col:{{.*}} referenced functional_cast_result 'typeof (double(int_value))':'double'{{$}}
|
||||
// CHECK-NEXT: TypeOfExprType {{.*}} 'typeof (double(int_value))' sugar{{( imported)?}}{{$}}
|
||||
// CHECK-NEXT: ParenExpr {{.*}} <col:{{.*}}, col:{{.*}}> 'double'{{$}}
|
||||
// CHECK-NEXT: CXXFunctionalCastExpr {{.*}} <col:{{.*}}, col:{{.*}}> 'double' functional cast to double <NoOp>{{$}}
|
||||
// CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'double' <IntegralToFloating> part_of_explicit_cast{{$}}
|
||||
// CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'int' <LValueToRValue> part_of_explicit_cast{{$}}
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} <col:{{.*}}> 'int' lvalue Var {{.*}} 'int_value' 'int'{{$}}
|
||||
|
||||
// CXXBoolLiteralExpr
|
||||
bool_literal_result *bool_ptr = &boolean;
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
// RUN: %clang_cc1 -triple x86_64-linux-gnu -fsyntax-only -ast-dump %s | FileCheck %s
|
||||
|
||||
// We are checking that implicit casts don't get marked with 'part_of_explicit_cast',
|
||||
// while in explicit casts, the implicitly-inserted implicit casts are marked with 'part_of_explicit_cast'
|
||||
|
||||
unsigned char implicitcast_0(unsigned int x) {
|
||||
// CHECK: FunctionDecl {{.*}} <{{.*}}, line:{{.*}}> line:{{.*}} implicitcast_0 'unsigned char (unsigned int)'{{$}}
|
||||
// CHECK: ImplicitCastExpr {{.*}} <col:{{.*}}> 'unsigned char' <IntegralCast>{{$}}
|
||||
// CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'unsigned int' <LValueToRValue>{{$}}
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} <col:{{.*}}> 'unsigned int' lvalue ParmVar {{.*}} 'x' 'unsigned int'{{$}}
|
||||
return x;
|
||||
}
|
||||
|
||||
signed char implicitcast_1(unsigned int x) {
|
||||
// CHECK: FunctionDecl {{.*}} <{{.*}}, line:{{.*}}> line:{{.*}} implicitcast_1 'signed char (unsigned int)'{{$}}
|
||||
// CHECK: ImplicitCastExpr {{.*}} <col:{{.*}}> 'signed char' <IntegralCast>{{$}}
|
||||
// CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'unsigned int' <LValueToRValue>{{$}}
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} <col:{{.*}}> 'unsigned int' lvalue ParmVar {{.*}} 'x' 'unsigned int'{{$}}
|
||||
return x;
|
||||
}
|
||||
|
||||
unsigned char implicitcast_2(signed int x) {
|
||||
// CHECK: FunctionDecl {{.*}} <{{.*}}, line:{{.*}}> line:{{.*}} implicitcast_2 'unsigned char (int)'{{$}}
|
||||
// CHECK: ImplicitCastExpr {{.*}} <col:{{.*}}> 'unsigned char' <IntegralCast>{{$}}
|
||||
// CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'int' <LValueToRValue>{{$}}
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} <col:{{.*}}> 'int' lvalue ParmVar {{.*}} 'x' 'int'{{$}}
|
||||
return x;
|
||||
}
|
||||
|
||||
signed char implicitcast_3(signed int x) {
|
||||
// CHECK: FunctionDecl {{.*}} <{{.*}}, line:{{.*}}> line:{{.*}} implicitcast_3 'signed char (int)'{{$}}
|
||||
// CHECK: ImplicitCastExpr {{.*}} <col:{{.*}}> 'signed char' <IntegralCast>{{$}}
|
||||
// CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'int' <LValueToRValue>{{$}}
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} <col:{{.*}}> 'int' lvalue ParmVar {{.*}} 'x' 'int'{{$}}
|
||||
return x;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
unsigned char cstylecast_0(unsigned int x) {
|
||||
// CHECK: FunctionDecl {{.*}} <{{.*}}, line:{{.*}}> line:{{.*}} cstylecast_0 'unsigned char (unsigned int)'{{$}}
|
||||
// CHECK: CStyleCastExpr {{.*}} <col:{{.*}}> 'unsigned char' <IntegralCast>{{$}}
|
||||
// CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'unsigned int' <LValueToRValue> part_of_explicit_cast{{$}}
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} <col:{{.*}}> 'unsigned int' lvalue ParmVar {{.*}} 'x' 'unsigned int'{{$}}
|
||||
return (unsigned char)x;
|
||||
}
|
||||
|
||||
signed char cstylecast_1(unsigned int x) {
|
||||
// CHECK: FunctionDecl {{.*}} <{{.*}}, line:{{.*}}> line:{{.*}} cstylecast_1 'signed char (unsigned int)'{{$}}
|
||||
// CHECK: CStyleCastExpr {{.*}} <col:{{.*}}> 'signed char' <IntegralCast>{{$}}
|
||||
// CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'unsigned int' <LValueToRValue> part_of_explicit_cast{{$}}
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} <col:{{.*}}> 'unsigned int' lvalue ParmVar {{.*}} 'x' 'unsigned int'{{$}}
|
||||
return (signed char)x;
|
||||
}
|
||||
|
||||
unsigned char cstylecast_2(signed int x) {
|
||||
// CHECK: FunctionDecl {{.*}} <{{.*}}, line:{{.*}}> line:{{.*}} cstylecast_2 'unsigned char (int)'{{$}}
|
||||
// CHECK: CStyleCastExpr {{.*}} <col:{{.*}}> 'unsigned char' <IntegralCast>{{$}}
|
||||
// CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'int' <LValueToRValue> part_of_explicit_cast{{$}}
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} <col:{{.*}}> 'int' lvalue ParmVar {{.*}} 'x' 'int'{{$}}
|
||||
return (unsigned char)x;
|
||||
}
|
||||
|
||||
signed char cstylecast_3(signed int x) {
|
||||
// CHECK: FunctionDecl {{.*}} <{{.*}}, line:{{.*}}> line:{{.*}} cstylecast_3 'signed char (int)'{{$}}
|
||||
// CHECK: CStyleCastExpr {{.*}} <col:{{.*}}> 'signed char' <IntegralCast>{{$}}
|
||||
// CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'int' <LValueToRValue> part_of_explicit_cast{{$}}
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} <col:{{.*}}> 'int' lvalue ParmVar {{.*}} 'x' 'int'{{$}}
|
||||
return (signed char)x;
|
||||
}
|
|
@ -0,0 +1,155 @@
|
|||
// RUN: %clang_cc1 -triple x86_64-linux-gnu -fsyntax-only -ast-dump %s | FileCheck %s
|
||||
|
||||
// We are checking that implicit casts don't get marked with 'part_of_explicit_cast',
|
||||
// while in explicit casts, the implicitly-inserted implicit casts are marked with 'part_of_explicit_cast'
|
||||
|
||||
unsigned char implicitcast_0(unsigned int x) {
|
||||
// CHECK: FunctionDecl {{.*}} <{{.*}}, line:{{.*}}> line:{{.*}} implicitcast_0 'unsigned char (unsigned int)'{{$}}
|
||||
// CHECK: ImplicitCastExpr {{.*}} <col:{{.*}}> 'unsigned char' <IntegralCast>{{$}}
|
||||
// CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'unsigned int' <LValueToRValue>{{$}}
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} <col:{{.*}}> 'unsigned int' lvalue ParmVar {{.*}} 'x' 'unsigned int'{{$}}
|
||||
return x;
|
||||
}
|
||||
|
||||
signed char implicitcast_1(unsigned int x) {
|
||||
// CHECK: FunctionDecl {{.*}} <{{.*}}, line:{{.*}}> line:{{.*}} implicitcast_1 'signed char (unsigned int)'{{$}}
|
||||
// CHECK: ImplicitCastExpr {{.*}} <col:{{.*}}> 'signed char' <IntegralCast>{{$}}
|
||||
// CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'unsigned int' <LValueToRValue>{{$}}
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} <col:{{.*}}> 'unsigned int' lvalue ParmVar {{.*}} 'x' 'unsigned int'{{$}}
|
||||
return x;
|
||||
}
|
||||
|
||||
unsigned char implicitcast_2(signed int x) {
|
||||
// CHECK: FunctionDecl {{.*}} <{{.*}}, line:{{.*}}> line:{{.*}} implicitcast_2 'unsigned char (int)'{{$}}
|
||||
// CHECK: ImplicitCastExpr {{.*}} <col:{{.*}}> 'unsigned char' <IntegralCast>{{$}}
|
||||
// CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'int' <LValueToRValue>{{$}}
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} <col:{{.*}}> 'int' lvalue ParmVar {{.*}} 'x' 'int'{{$}}
|
||||
return x;
|
||||
}
|
||||
|
||||
signed char implicitcast_3(signed int x) {
|
||||
// CHECK: FunctionDecl {{.*}} <{{.*}}, line:{{.*}}> line:{{.*}} implicitcast_3 'signed char (int)'{{$}}
|
||||
// CHECK: ImplicitCastExpr {{.*}} <col:{{.*}}> 'signed char' <IntegralCast>{{$}}
|
||||
// CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'int' <LValueToRValue>{{$}}
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} <col:{{.*}}> 'int' lvalue ParmVar {{.*}} 'x' 'int'{{$}}
|
||||
return x;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
unsigned char cstylecast_0(unsigned int x) {
|
||||
// CHECK: FunctionDecl {{.*}} <{{.*}}, line:{{.*}}> line:{{.*}} cstylecast_0 'unsigned char (unsigned int)'{{$}}
|
||||
// CHECK: CStyleCastExpr {{.*}} <col:{{.*}}> 'unsigned char' <NoOp>{{$}}
|
||||
// CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'unsigned char' <IntegralCast> part_of_explicit_cast{{$}}
|
||||
// CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'unsigned int' <LValueToRValue> part_of_explicit_cast{{$}}
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} <col:{{.*}}> 'unsigned int' lvalue ParmVar {{.*}} 'x' 'unsigned int'{{$}}
|
||||
return (unsigned char)x;
|
||||
}
|
||||
|
||||
signed char cstylecast_1(unsigned int x) {
|
||||
// CHECK: FunctionDecl {{.*}} <{{.*}}, line:{{.*}}> line:{{.*}} cstylecast_1 'signed char (unsigned int)'{{$}}
|
||||
// CHECK: CStyleCastExpr {{.*}} <col:{{.*}}> 'signed char' <NoOp>{{$}}
|
||||
// CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'signed char' <IntegralCast> part_of_explicit_cast{{$}}
|
||||
// CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'unsigned int' <LValueToRValue> part_of_explicit_cast{{$}}
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} <col:{{.*}}> 'unsigned int' lvalue ParmVar {{.*}} 'x' 'unsigned int'{{$}}
|
||||
return (signed char)x;
|
||||
}
|
||||
|
||||
unsigned char cstylecast_2(signed int x) {
|
||||
// CHECK: FunctionDecl {{.*}} <{{.*}}, line:{{.*}}> line:{{.*}} cstylecast_2 'unsigned char (int)'{{$}}
|
||||
// CHECK: CStyleCastExpr {{.*}} <col:{{.*}}> 'unsigned char' <NoOp>{{$}}
|
||||
// CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'unsigned char' <IntegralCast> part_of_explicit_cast{{$}}
|
||||
// CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'int' <LValueToRValue> part_of_explicit_cast{{$}}
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} <col:{{.*}}> 'int' lvalue ParmVar {{.*}} 'x' 'int'{{$}}
|
||||
return (unsigned char)x;
|
||||
}
|
||||
|
||||
signed char cstylecast_3(signed int x) {
|
||||
// CHECK: FunctionDecl {{.*}} <{{.*}}, line:{{.*}}> line:{{.*}} cstylecast_3 'signed char (int)'{{$}}
|
||||
// CHECK: CStyleCastExpr {{.*}} <col:{{.*}}> 'signed char' <NoOp>{{$}}
|
||||
// CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'signed char' <IntegralCast> part_of_explicit_cast{{$}}
|
||||
// CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'int' <LValueToRValue> part_of_explicit_cast{{$}}
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} <col:{{.*}}> 'int' lvalue ParmVar {{.*}} 'x' 'int'{{$}}
|
||||
return (signed char)x;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
unsigned char cxxstaticcast_0(unsigned int x) {
|
||||
// CHECK: FunctionDecl {{.*}} <{{.*}}, line:{{.*}}> line:{{.*}} cxxstaticcast_0 'unsigned char (unsigned int)'{{$}}
|
||||
// CHECK: CXXStaticCastExpr {{.*}} <col:{{.*}}> 'unsigned char' static_cast<unsigned char> <NoOp>{{$}}
|
||||
// CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'unsigned char' <IntegralCast> part_of_explicit_cast{{$}}
|
||||
// CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'unsigned int' <LValueToRValue> part_of_explicit_cast{{$}}
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} <col:{{.*}}> 'unsigned int' lvalue ParmVar {{.*}} 'x' 'unsigned int'{{$}}
|
||||
return static_cast<unsigned char>(x);
|
||||
}
|
||||
|
||||
signed char cxxstaticcast_1(unsigned int x) {
|
||||
// CHECK: FunctionDecl {{.*}} <{{.*}}, line:{{.*}}> line:{{.*}} cxxstaticcast_1 'signed char (unsigned int)'{{$}}
|
||||
// CHECK: CXXStaticCastExpr {{.*}} <col:{{.*}}> 'signed char' static_cast<signed char> <NoOp>{{$}}
|
||||
// CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'signed char' <IntegralCast> part_of_explicit_cast{{$}}
|
||||
// CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'unsigned int' <LValueToRValue> part_of_explicit_cast{{$}}
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} <col:{{.*}}> 'unsigned int' lvalue ParmVar {{.*}} 'x' 'unsigned int'{{$}}
|
||||
return static_cast<signed char>(x);
|
||||
}
|
||||
|
||||
unsigned char cxxstaticcast_2(signed int x) {
|
||||
// CHECK: FunctionDecl {{.*}} <{{.*}}, line:{{.*}}> line:{{.*}} cxxstaticcast_2 'unsigned char (int)'{{$}}
|
||||
// CHECK: CXXStaticCastExpr {{.*}} <col:{{.*}}> 'unsigned char' static_cast<unsigned char> <NoOp>{{$}}
|
||||
// CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'unsigned char' <IntegralCast> part_of_explicit_cast{{$}}
|
||||
// CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'int' <LValueToRValue> part_of_explicit_cast{{$}}
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} <col:{{.*}}> 'int' lvalue ParmVar {{.*}} 'x' 'int'{{$}}
|
||||
return static_cast<unsigned char>(x);
|
||||
}
|
||||
|
||||
signed char cxxstaticcast_3(signed int x) {
|
||||
// CHECK: FunctionDecl {{.*}} <{{.*}}, line:{{.*}}> line:{{.*}} cxxstaticcast_3 'signed char (int)'{{$}}
|
||||
// CHECK: CXXStaticCastExpr {{.*}} <col:{{.*}}> 'signed char' static_cast<signed char> <NoOp>{{$}}
|
||||
// CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'signed char' <IntegralCast> part_of_explicit_cast{{$}}
|
||||
// CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'int' <LValueToRValue> part_of_explicit_cast{{$}}
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} <col:{{.*}}> 'int' lvalue ParmVar {{.*}} 'x' 'int'{{$}}
|
||||
return static_cast<signed char>(x);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
using UnsignedChar = unsigned char;
|
||||
using SignedChar = signed char;
|
||||
using UnsignedInt = unsigned int;
|
||||
using SignedInt = signed int;
|
||||
|
||||
UnsignedChar cxxfunctionalcast_0(UnsignedInt x) {
|
||||
// CHECK: FunctionDecl {{.*}} <{{.*}}, line:{{.*}}> line:{{.*}} cxxfunctionalcast_0 'UnsignedChar (UnsignedInt)'{{$}}
|
||||
// CHECK: CXXFunctionalCastExpr {{.*}} <col:{{.*}}> 'UnsignedChar':'unsigned char' functional cast to UnsignedChar <NoOp>{{$}}
|
||||
// CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'UnsignedChar':'unsigned char' <IntegralCast> part_of_explicit_cast{{$}}
|
||||
// CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'UnsignedInt':'unsigned int' <LValueToRValue> part_of_explicit_cast{{$}}
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} <col:{{.*}}> 'UnsignedInt':'unsigned int' lvalue ParmVar {{.*}} 'x' 'UnsignedInt':'unsigned int'{{$}}
|
||||
return UnsignedChar(x);
|
||||
}
|
||||
|
||||
SignedChar cxxfunctionalcast_1(UnsignedInt x) {
|
||||
// CHECK: FunctionDecl {{.*}} <{{.*}}, line:{{.*}}> line:{{.*}} cxxfunctionalcast_1 'SignedChar (UnsignedInt)'{{$}}
|
||||
// CHECK: CXXFunctionalCastExpr {{.*}} <col:{{.*}}> 'SignedChar':'signed char' functional cast to SignedChar <NoOp>{{$}}
|
||||
// CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'SignedChar':'signed char' <IntegralCast> part_of_explicit_cast{{$}}
|
||||
// CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'UnsignedInt':'unsigned int' <LValueToRValue> part_of_explicit_cast{{$}}
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} <col:{{.*}}> 'UnsignedInt':'unsigned int' lvalue ParmVar {{.*}} 'x' 'UnsignedInt':'unsigned int'{{$}}
|
||||
return SignedChar(x);
|
||||
}
|
||||
|
||||
UnsignedChar cxxfunctionalcast_2(SignedInt x) {
|
||||
// CHECK: FunctionDecl {{.*}} <{{.*}}, line:{{.*}}> line:{{.*}} cxxfunctionalcast_2 'UnsignedChar (SignedInt)'{{$}}
|
||||
// CHECK: CXXFunctionalCastExpr {{.*}} <col:{{.*}}> 'UnsignedChar':'unsigned char' functional cast to UnsignedChar <NoOp>{{$}}
|
||||
// CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'UnsignedChar':'unsigned char' <IntegralCast> part_of_explicit_cast{{$}}
|
||||
// CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'SignedInt':'int' <LValueToRValue> part_of_explicit_cast{{$}}
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} <col:{{.*}}> 'SignedInt':'int' lvalue ParmVar {{.*}} 'x' 'SignedInt':'int'{{$}}
|
||||
return UnsignedChar(x);
|
||||
}
|
||||
|
||||
SignedChar cxxfunctionalcast_3(SignedInt x) {
|
||||
// CHECK: FunctionDecl {{.*}} <{{.*}}, line:{{.*}}> line:{{.*}} cxxfunctionalcast_3 'SignedChar (SignedInt)'{{$}}
|
||||
// CHECK: CXXFunctionalCastExpr {{.*}} <col:{{.*}}> 'SignedChar':'signed char' functional cast to SignedChar <NoOp>{{$}}
|
||||
// CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'SignedChar':'signed char' <IntegralCast> part_of_explicit_cast{{$}}
|
||||
// CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'SignedInt':'int' <LValueToRValue> part_of_explicit_cast{{$}}
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} <col:{{.*}}> 'SignedInt':'int' lvalue ParmVar {{.*}} 'x' 'SignedInt':'int'{{$}}
|
||||
return SignedChar(x);
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
// RUN: %clang_cc1 -triple x86_64-linux-gnu -fsyntax-only -ast-dump %s | FileCheck %s
|
||||
// expected-no-diagnostics
|
||||
|
||||
typedef __attribute__((ext_vector_type(2))) char char2;
|
||||
|
||||
void vectorIncrementDecrementOps() {
|
||||
// CHECK: FunctionDecl {{.*}} <{{.*}}, line:{{.*}}> line:{{.*}} vectorIncrementDecrementOps 'void (void)'{{$}}
|
||||
// CHECK: CStyleCastExpr {{.*}} <col:{{.*}}> 'char2':'char __attribute__((ext_vector_type(2)))' <VectorSplat>{{$}}
|
||||
// CHECK-NEXT: ImplicitCastExpr {{.*}} <col:{{.*}}> 'char' <IntegralCast> part_of_explicit_cast{{$}}
|
||||
// CHECK-NEXT: IntegerLiteral {{.*}} <col:{{.*}}> 'int' 1{{$}}
|
||||
char2 A = (char2)(1);
|
||||
A++;
|
||||
}
|
Loading…
Reference in New Issue