зеркало из https://github.com/microsoft/clang-1.git
Implement C++ semantics for C-style and functional-style casts. This regresses Clang extension conversions, like vectors, but allows conversions via constructors and conversion operators.
Add custom conversions to static_cast. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@77076 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
10aebbb5c8
Коммит
9cc11e7003
|
@ -1395,36 +1395,46 @@ def note_property_impl_required : Note<
|
|||
|
||||
|
||||
// C++ casts
|
||||
def err_bad_cxx_cast_generic : Error<"%0 from %2 to %1 is not allowed">;
|
||||
def err_bad_cxx_cast_rvalue : Error<"%0 from rvalue to reference type %1">;
|
||||
// These messages adhere to the TryCast pattern: %0 is an int specifying the
|
||||
// cast type, %1 is the source type, %2 is the destination type.
|
||||
def err_bad_cxx_cast_generic : Error<
|
||||
"%select{const_cast|static_cast|reinterpret_cast|dynamic_cast|C-style cast|"
|
||||
"functional-style cast}0 from %1 to %2 is not allowed">;
|
||||
def err_bad_cxx_cast_rvalue : Error<
|
||||
"%select{const_cast|static_cast|reinterpret_cast|dynamic_cast|C-style cast|"
|
||||
"functional-style cast}0 from rvalue to reference type %2">;
|
||||
def err_bad_cxx_cast_const_away : Error<
|
||||
"%0 from %2 to %1 casts away constness">;
|
||||
"%select{const_cast|static_cast|reinterpret_cast|dynamic_cast|C-style cast|"
|
||||
"functional-style cast}0 from %1 to %2 casts away constness">;
|
||||
def err_bad_const_cast_dest : Error<
|
||||
"const_cast to %0, which is not a reference, pointer-to-object, "
|
||||
"or pointer-to-data-member">;
|
||||
|
||||
def err_bad_reinterpret_cast_same_type : Error<
|
||||
"source and destination type of reinterpret_cast are not distinct">;
|
||||
def ext_reinterpret_cast_fn_obj : Extension<
|
||||
"reinterpret_cast between pointer-to-function and pointer-to-object is "
|
||||
"an extension">;
|
||||
|
||||
"%select{const_cast||||C-style cast|functional-style cast}0 to %2, "
|
||||
"which is not a reference, pointer-to-object, or pointer-to-data-member">;
|
||||
def ext_cast_fn_obj : Extension<
|
||||
"cast between pointer-to-function and pointer-to-object is an extension">;
|
||||
def err_bad_reinterpret_cast_small_int : Error<
|
||||
"cast from pointer to smaller type %0 loses information">;
|
||||
"cast from pointer to smaller type %2 loses information">;
|
||||
def err_bad_lvalue_to_rvalue_cast : Error<
|
||||
"cannot cast from lvalue of type %1 to rvalue reference type %2; types are "
|
||||
"not compatible">;
|
||||
def err_bad_static_cast_pointer_nonpointer : Error<
|
||||
"cannot cast from type %1 to pointer type %2">;
|
||||
def err_bad_static_cast_member_pointer_nonmp : Error<
|
||||
"cannot cast from type %1 to member pointer type %2">;
|
||||
|
||||
// These messages don't adhere to the pattern.
|
||||
// FIXME: Display the path somehow better.
|
||||
def err_ambiguous_base_to_derived_cast : Error<
|
||||
"ambiguous cast from base %0 to derived %1:%2">;
|
||||
def err_static_downcast_via_virtual : Error<
|
||||
"cannot cast %0 to %1 via virtual base %2">;
|
||||
def err_downcast_from_inaccessible_base : Error<
|
||||
"cannot cast %1 to %0 due to inaccessible conversion path">;
|
||||
def err_bad_dynamic_cast_not_ref_or_ptr : Error<
|
||||
"%0 is not a reference or pointer">;
|
||||
def err_bad_dynamic_cast_not_class : Error<"%0 is not a class">;
|
||||
def err_bad_dynamic_cast_incomplete : Error<"%0 is an incomplete type">;
|
||||
def err_bad_dynamic_cast_not_ptr : Error<"%0 is not a pointer">;
|
||||
def err_bad_dynamic_cast_not_polymorphic : Error<"%0 is not polymorphic">;
|
||||
// FIXME: Display the path somehow better.
|
||||
def err_ambiguous_base_to_derived_cast : Error<
|
||||
"ambiguous static_cast from base %0 to derived %1:%2">;
|
||||
def err_static_downcast_via_virtual : Error<
|
||||
"cannot cast %0 to %1 via virtual base %2">;
|
||||
def err_bad_lvalue_to_rvalue_cast : Error<
|
||||
"cannot cast from lvalue of type %0 to rvalue reference to %1; types are "
|
||||
"not compatible">;
|
||||
|
||||
// Other C++ expressions
|
||||
def err_need_header_before_typeid : Error<
|
||||
|
|
|
@ -3169,9 +3169,10 @@ public:
|
|||
bool AllowExplicit = false,
|
||||
bool ForceRValue = false);
|
||||
|
||||
/// CheckCastTypes - Check type constraints for casting between types.
|
||||
/// CheckCastTypes - Check type constraints for casting between types under
|
||||
/// C semantics.
|
||||
bool CheckCastTypes(SourceRange TyRange, QualType CastTy, Expr *&CastExpr);
|
||||
|
||||
|
||||
// CheckVectorCast - check type constraints for vectors.
|
||||
// Since vectors are an extension, there are no C standard reference for this.
|
||||
// We allow casting between vectors and integer datatypes of the same size.
|
||||
|
@ -3184,7 +3185,11 @@ public:
|
|||
// or vectors and the element type of that vector.
|
||||
// returns true if the cast is invalid
|
||||
bool CheckExtVectorCast(SourceRange R, QualType VectorTy, QualType Ty);
|
||||
|
||||
|
||||
/// CXXCheckCStyleCast - Check constraints of a C-style or function-style
|
||||
/// cast under C++ semantics.
|
||||
bool CXXCheckCStyleCast(SourceRange R, QualType CastTy, Expr *&CastExpr);
|
||||
|
||||
/// CheckMessageArgumentTypes - Check types in an Obj-C message send.
|
||||
/// \param Method - May be null.
|
||||
/// \param [out] ReturnType - The return type of the send.
|
||||
|
@ -3196,7 +3201,7 @@ public:
|
|||
|
||||
/// CheckCXXBooleanCondition - Returns true if conversion to bool is invalid.
|
||||
bool CheckCXXBooleanCondition(Expr *&CondExpr);
|
||||
|
||||
|
||||
/// ConvertIntegerToTypeWarnOnOverflow - Convert the specified APInt to have
|
||||
/// the specified width and sign. If an overflow occurs, detect it and emit
|
||||
/// the specified diagnostic.
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -2919,14 +2919,15 @@ Sema::ActOnInitList(SourceLocation LBraceLoc, MultiExprArg initlist,
|
|||
|
||||
/// CheckCastTypes - Check type constraints for casting between types.
|
||||
bool Sema::CheckCastTypes(SourceRange TyR, QualType castType, Expr *&castExpr) {
|
||||
if (getLangOptions().CPlusPlus)
|
||||
return CXXCheckCStyleCast(TyR, castType, castExpr);
|
||||
|
||||
UsualUnaryConversions(castExpr);
|
||||
|
||||
// C99 6.5.4p2: the cast type needs to be void or scalar and the expression
|
||||
// type needs to be scalar.
|
||||
if (castType->isVoidType()) {
|
||||
// Cast to void allows any expr type.
|
||||
} else if (castType->isDependentType() || castExpr->isTypeDependent()) {
|
||||
// We can't check any more until template instantiation time.
|
||||
} else if (!castType->isScalarType() && !castType->isVectorType()) {
|
||||
if (Context.getCanonicalType(castType).getUnqualifiedType() ==
|
||||
Context.getCanonicalType(castExpr->getType().getUnqualifiedType()) &&
|
||||
|
@ -3040,7 +3041,8 @@ Sema::ActOnCastExpr(SourceLocation LParenLoc, TypeTy *Ty,
|
|||
|
||||
if (CheckCastTypes(SourceRange(LParenLoc, RParenLoc), castType, castExpr))
|
||||
return ExprError();
|
||||
return Owned(new (Context) CStyleCastExpr(castType, castExpr, castType,
|
||||
return Owned(new (Context) CStyleCastExpr(castType.getNonReferenceType(),
|
||||
castExpr, castType,
|
||||
LParenLoc, RParenLoc));
|
||||
}
|
||||
|
||||
|
|
|
@ -1136,7 +1136,7 @@ bool Sema::isObjCPointerConversion(QualType FromType, QualType ToType,
|
|||
|
||||
/// CheckPointerConversion - Check the pointer conversion from the
|
||||
/// expression From to the type ToType. This routine checks for
|
||||
/// ambiguous (FIXME: or inaccessible) derived-to-base pointer
|
||||
/// ambiguous or inaccessible derived-to-base pointer
|
||||
/// conversions for which IsPointerConversion has already returned
|
||||
/// true. It returns true and produces a diagnostic if there was an
|
||||
/// error, or returns false otherwise.
|
||||
|
|
|
@ -5,9 +5,9 @@ void f() {
|
|||
int x, *px;
|
||||
|
||||
// Type id.
|
||||
(T())x; // expected-error {{used type 'T ()'}}
|
||||
(T())+x; // expected-error {{used type 'T ()'}}
|
||||
(T())*px; // expected-error {{used type 'T ()'}}
|
||||
(T())x; // expected-error {{cast from 'int' to 'T ()'}}
|
||||
(T())+x; // expected-error {{cast from 'int' to 'T ()'}}
|
||||
(T())*px; // expected-error {{cast from 'int' to 'T ()'}}
|
||||
|
||||
// Expression.
|
||||
x = (T());
|
||||
|
|
|
@ -0,0 +1,231 @@
|
|||
// RUN: clang-cc -fsyntax-only -verify -faccess-control %s
|
||||
|
||||
struct A {};
|
||||
|
||||
// ----------- const_cast --------------
|
||||
|
||||
typedef char c;
|
||||
typedef c *cp;
|
||||
typedef cp *cpp;
|
||||
typedef cpp *cppp;
|
||||
typedef cppp &cpppr;
|
||||
typedef const cppp &cpppcr;
|
||||
typedef const char cc;
|
||||
typedef cc *ccp;
|
||||
typedef volatile ccp ccvp;
|
||||
typedef ccvp *ccvpp;
|
||||
typedef const volatile ccvpp ccvpcvp;
|
||||
typedef ccvpcvp *ccvpcvpp;
|
||||
typedef int iar[100];
|
||||
typedef iar &iarr;
|
||||
typedef int (*f)(int);
|
||||
|
||||
void t_cc()
|
||||
{
|
||||
ccvpcvpp var = 0;
|
||||
// Cast away deep consts and volatiles.
|
||||
char ***var2 = (cppp)(var);
|
||||
char ***const &var3 = var2;
|
||||
// Const reference to reference.
|
||||
char ***&var4 = (cpppr)(var3);
|
||||
// Drop reference. Intentionally without qualifier change.
|
||||
char *** var5 = (cppp)(var4);
|
||||
const int ar[100] = {0};
|
||||
// Array decay. Intentionally without qualifier change.
|
||||
int *pi = (int*)(ar);
|
||||
f fp = 0;
|
||||
// Don't misidentify fn** as a function pointer.
|
||||
f *fpp = (f*)(&fp);
|
||||
int const A::* const A::*icapcap = 0;
|
||||
int A::* A::* iapap = (int A::* A::*)(icapcap);
|
||||
}
|
||||
|
||||
// ----------- static_cast -------------
|
||||
|
||||
struct B : public A {}; // Single public base.
|
||||
struct C1 : public virtual B {}; // Single virtual base.
|
||||
struct C2 : public virtual B {};
|
||||
struct D : public C1, public C2 {}; // Diamond
|
||||
struct E : private A {}; // Single private base.
|
||||
struct F : public C1 {}; // Single path to B with virtual.
|
||||
struct G1 : public B {};
|
||||
struct G2 : public B {};
|
||||
struct H : public G1, public G2 {}; // Ambiguous path to B.
|
||||
|
||||
enum Enum { En1, En2 };
|
||||
enum Onom { On1, On2 };
|
||||
|
||||
struct Co1 { operator int(); };
|
||||
struct Co2 { Co2(int); };
|
||||
struct Co3 { };
|
||||
struct Co4 { Co4(Co3); operator Co3(); };
|
||||
|
||||
// Explicit implicits
|
||||
void t_529_2()
|
||||
{
|
||||
int i = 1;
|
||||
(void)(float)(i);
|
||||
double d = 1.0;
|
||||
(void)(float)(d);
|
||||
(void)(int)(d);
|
||||
(void)(char)(i);
|
||||
(void)(unsigned long)(i);
|
||||
(void)(int)(En1);
|
||||
(void)(double)(En1);
|
||||
(void)(int&)(i);
|
||||
(void)(const int&)(i);
|
||||
|
||||
int ar[1];
|
||||
(void)(const int*)(ar);
|
||||
(void)(void (*)())(t_529_2);
|
||||
|
||||
(void)(void*)(0);
|
||||
(void)(void*)((int*)0);
|
||||
(void)(volatile const void*)((const int*)0);
|
||||
(void)(A*)((B*)0);
|
||||
(void)(A&)(*((B*)0));
|
||||
(void)(const B*)((C1*)0);
|
||||
(void)(B&)(*((C1*)0));
|
||||
(void)(A*)((D*)0);
|
||||
(void)(const A&)(*((D*)0));
|
||||
(void)(int B::*)((int A::*)0);
|
||||
(void)(void (B::*)())((void (A::*)())0);
|
||||
(void)(A*)((E*)0); // C-style cast ignores access control
|
||||
(void)(void*)((const int*)0); // const_cast appended
|
||||
|
||||
(void)(int)(Co1());
|
||||
(void)(Co2)(1);
|
||||
(void)(Co3)((Co4)(Co3()));
|
||||
|
||||
// Bad code below
|
||||
//(void)(A*)((H*)0); // {{static_cast from 'struct H *' to 'struct A *' is not allowed}}
|
||||
}
|
||||
|
||||
// Anything to void
|
||||
void t_529_4()
|
||||
{
|
||||
(void)(1);
|
||||
(void)(t_529_4);
|
||||
}
|
||||
|
||||
// Static downcasts
|
||||
void t_529_5_8()
|
||||
{
|
||||
(void)(B*)((A*)0);
|
||||
(void)(B&)(*((A*)0));
|
||||
(void)(const G1*)((A*)0);
|
||||
(void)(const G1&)(*((A*)0));
|
||||
(void)(B*)((const A*)0); // const_cast appended
|
||||
(void)(B&)(*((const A*)0)); // const_cast appended
|
||||
(void)(E*)((A*)0); // access control ignored
|
||||
(void)(E&)(*((A*)0)); // access control ignored
|
||||
|
||||
// Bad code below
|
||||
|
||||
(void)(C1*)((A*)0); // expected-error {{cannot cast 'struct A *' to 'struct C1 *' via virtual base 'struct B'}}
|
||||
(void)(C1&)(*((A*)0)); // expected-error {{cannot cast 'struct A' to 'struct C1 &' via virtual base 'struct B'}}
|
||||
(void)(D*)((A*)0); // expected-error {{cannot cast 'struct A *' to 'struct D *' via virtual base 'struct B'}}
|
||||
(void)(D&)(*((A*)0)); // expected-error {{cannot cast 'struct A' to 'struct D &' via virtual base 'struct B'}}
|
||||
(void)(H*)((A*)0); // expected-error {{ambiguous cast from base 'struct A' to derived 'struct H':\n struct A -> struct B -> struct G1 -> struct H\n struct A -> struct B -> struct G2 -> struct H}}
|
||||
(void)(H&)(*((A*)0)); // expected-error {{ambiguous cast from base 'struct A' to derived 'struct H':\n struct A -> struct B -> struct G1 -> struct H\n struct A -> struct B -> struct G2 -> struct H}}
|
||||
|
||||
// TODO: Test DR427. This requires user-defined conversions, though.
|
||||
}
|
||||
|
||||
// Enum conversions
|
||||
void t_529_7()
|
||||
{
|
||||
(void)(Enum)(1);
|
||||
(void)(Enum)(1.0);
|
||||
(void)(Onom)(En1);
|
||||
|
||||
// Bad code below
|
||||
|
||||
(void)(Enum)((int*)0); // expected-error {{C-style cast from 'int *' to 'enum Enum' is not allowed}}
|
||||
}
|
||||
|
||||
// Void pointer to object pointer
|
||||
void t_529_10()
|
||||
{
|
||||
(void)(int*)((void*)0);
|
||||
(void)(const A*)((void*)0);
|
||||
(void)(int*)((const void*)0); // const_cast appended
|
||||
}
|
||||
|
||||
// Member pointer upcast.
|
||||
void t_529_9()
|
||||
{
|
||||
(void)(int A::*)((int B::*)0);
|
||||
|
||||
// Bad code below
|
||||
(void)(int A::*)((int H::*)0); // expected-error {{ambiguous conversion from pointer to member of derived class 'struct H'}}
|
||||
(void)(int A::*)((int F::*)0); // expected-error {{conversion from pointer to member of class 'struct F'}}
|
||||
}
|
||||
|
||||
// -------- reinterpret_cast -----------
|
||||
|
||||
enum test { testval = 1 };
|
||||
struct structure { int m; };
|
||||
typedef void (*fnptr)();
|
||||
|
||||
// Test conversion between pointer and integral types, as in p3 and p4.
|
||||
void integral_conversion()
|
||||
{
|
||||
void *vp = (void*)(testval);
|
||||
long l = (long)(vp);
|
||||
(void)(float*)(l);
|
||||
fnptr fnp = (fnptr)(l);
|
||||
(void)(char)(fnp); // expected-error {{cast from pointer to smaller type 'char' loses information}}
|
||||
(void)(long)(fnp);
|
||||
}
|
||||
|
||||
void pointer_conversion()
|
||||
{
|
||||
int *p1 = 0;
|
||||
float *p2 = (float*)(p1);
|
||||
structure *p3 = (structure*)(p2);
|
||||
typedef int **ppint;
|
||||
ppint *deep = (ppint*)(p3);
|
||||
(void)(fnptr*)(deep);
|
||||
}
|
||||
|
||||
void constness()
|
||||
{
|
||||
int ***const ipppc = 0;
|
||||
int const *icp = (int const*)(ipppc);
|
||||
(void)(int*)(icp); // const_cast appended
|
||||
int const *const **icpcpp = (int const* const**)(ipppc); // const_cast appended
|
||||
int *ip = (int*)(icpcpp);
|
||||
(void)(int const*)(ip);
|
||||
(void)(int const* const* const*)(ipppc);
|
||||
}
|
||||
|
||||
void fnptrs()
|
||||
{
|
||||
typedef int (*fnptr2)(int);
|
||||
fnptr fp = 0;
|
||||
(void)(fnptr2)(fp);
|
||||
void *vp = (void*)(fp);
|
||||
(void)(fnptr)(vp);
|
||||
}
|
||||
|
||||
void refs()
|
||||
{
|
||||
long l = 0;
|
||||
char &c = (char&)(l);
|
||||
// Bad: from rvalue
|
||||
(void)(int&)(&c); // expected-error {{C-style cast from rvalue to reference type 'int &'}}
|
||||
}
|
||||
|
||||
void memptrs()
|
||||
{
|
||||
const int structure::*psi = 0;
|
||||
(void)(const float structure::*)(psi);
|
||||
(void)(int structure::*)(psi); // const_cast appended
|
||||
|
||||
void (structure::*psf)() = 0;
|
||||
(void)(int (structure::*)())(psf);
|
||||
|
||||
(void)(void (structure::*)())(psi); // expected-error {{C-style cast from 'int const struct structure::*' to 'void (struct structure::*)()' is not allowed}}
|
||||
(void)(int structure::*)(psf); // expected-error {{C-style cast from 'void (struct structure::*)()' to 'int struct structure::*' is not allowed}}
|
||||
}
|
|
@ -50,7 +50,7 @@ void foo5()
|
|||
void foo6()
|
||||
{
|
||||
(void)(int(1)); //expression
|
||||
(void)(int())1; // expected-error{{used type}}
|
||||
(void)(int())1; // expected-error{{to 'int ()'}}
|
||||
}
|
||||
|
||||
// [dcl.ambig.res]p7:
|
||||
|
|
|
@ -19,7 +19,7 @@ void f() {
|
|||
(int(1)); // expected-warning {{expression result unused}}
|
||||
|
||||
// type-id
|
||||
(int())1; // expected-error {{used type 'int ()' where arithmetic or pointer type is required}}
|
||||
(int())1; // expected-error {{C-style cast from 'int' to 'int ()' is not allowed}}
|
||||
|
||||
// Declarations.
|
||||
int fd(T(a)); // expected-warning {{parentheses were disambiguated as a function declarator}}
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
// RUN: clang-cc -fsyntax-only -verify %s
|
||||
// RUN: clang-cc -fsyntax-only -verify -faccess-control %s
|
||||
|
||||
struct A {};
|
||||
struct B : public A {}; // Single public base.
|
||||
struct C1 : public virtual B {}; // Single virtual base.
|
||||
struct C2 : public virtual B {};
|
||||
struct D : public C1, public C2 {}; // Diamond
|
||||
struct E : private A {}; // Single private base.
|
||||
struct E : private A {}; // Single private base. expected-note 2 {{'private' inheritance specifier here}}
|
||||
struct F : public C1 {}; // Single path to B with virtual.
|
||||
struct G1 : public B {};
|
||||
struct G2 : public B {};
|
||||
|
@ -14,6 +14,11 @@ struct H : public G1, public G2 {}; // Ambiguous path to B.
|
|||
enum Enum { En1, En2 };
|
||||
enum Onom { On1, On2 };
|
||||
|
||||
struct Co1 { operator int(); };
|
||||
struct Co2 { Co2(int); };
|
||||
struct Co3 { };
|
||||
struct Co4 { Co4(Co3); operator Co3(); };
|
||||
|
||||
// Explicit implicits
|
||||
void t_529_2()
|
||||
{
|
||||
|
@ -45,7 +50,9 @@ void t_529_2()
|
|||
(void)static_cast<int B::*>((int A::*)0);
|
||||
(void)static_cast<void (B::*)()>((void (A::*)())0);
|
||||
|
||||
// TODO: User-defined conversions
|
||||
(void)static_cast<int>(Co1());
|
||||
(void)static_cast<Co2>(1);
|
||||
(void)static_cast<Co3>(static_cast<Co4>(Co3()));
|
||||
|
||||
// Bad code below
|
||||
|
||||
|
@ -80,11 +87,10 @@ void t_529_5_8()
|
|||
(void)static_cast<D&>(*((A*)0)); // expected-error {{cannot cast 'struct A' to 'struct D &' via virtual base 'struct B'}}
|
||||
(void)static_cast<B*>((const A*)0); // expected-error {{static_cast from 'struct A const *' to 'struct B *' casts away constness}}
|
||||
(void)static_cast<B&>(*((const A*)0)); // expected-error {{static_cast from 'struct A const' to 'struct B &' casts away constness}}
|
||||
// Accessibility is not yet tested
|
||||
//(void)static_cast<E*>((A*)0); // {{static_cast from 'struct A *' to 'struct E *' is not allowed}}
|
||||
//(void)static_cast<E&>(*((A*)0)); // {{static_cast from 'struct A' to 'struct E &' is not allowed}}
|
||||
(void)static_cast<H*>((A*)0); // expected-error {{ambiguous static_cast from base 'struct A' to derived 'struct H':\n struct A -> struct B -> struct G1 -> struct H\n struct A -> struct B -> struct G2 -> struct H}}
|
||||
(void)static_cast<H&>(*((A*)0)); // expected-error {{ambiguous static_cast from base 'struct A' to derived 'struct H':\n struct A -> struct B -> struct G1 -> struct H\n struct A -> struct B -> struct G2 -> struct H}}
|
||||
(void)static_cast<E*>((A*)0); // expected-error {{cannot cast 'struct A' to 'struct E' due to inaccessible}}
|
||||
(void)static_cast<E&>(*((A*)0)); // expected-error {{cannot cast 'struct A' to 'struct E' due to inaccessible}}
|
||||
(void)static_cast<H*>((A*)0); // expected-error {{ambiguous cast from base 'struct A' to derived 'struct H':\n struct A -> struct B -> struct G1 -> struct H\n struct A -> struct B -> struct G2 -> struct H}}
|
||||
(void)static_cast<H&>(*((A*)0)); // expected-error {{ambiguous cast from base 'struct A' to derived 'struct H':\n struct A -> struct B -> struct G1 -> struct H\n struct A -> struct B -> struct G2 -> struct H}}
|
||||
(void)static_cast<E*>((B*)0); // expected-error {{static_cast from 'struct B *' to 'struct E *' is not allowed}}
|
||||
(void)static_cast<E&>(*((B*)0)); // expected-error {{non-const lvalue reference to type 'struct E' cannot be initialized with a value of type 'struct B'}}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// RUN: clang-cc -fsyntax-only -verify %s
|
||||
|
||||
struct A { int x; };
|
||||
struct A { int x; }; // expected-note 2 {{candidate}}
|
||||
|
||||
class Base {
|
||||
public:
|
||||
|
@ -23,7 +23,7 @@ struct Constructible {
|
|||
template<typename T, typename U>
|
||||
struct CStyleCast0 {
|
||||
void f(T t) {
|
||||
(void)((U)t); // FIXME:ugly expected-error{{operand}}
|
||||
(void)((U)t); // expected-error{{C-style cast from 'struct A' to 'int'}}
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -36,7 +36,7 @@ template struct CStyleCast0<A, int>; // expected-note{{instantiation}}
|
|||
template<typename T, typename U>
|
||||
struct StaticCast0 {
|
||||
void f(T t) {
|
||||
(void)static_cast<U>(t); // expected-error{{static_cast}}
|
||||
(void)static_cast<U>(t); // expected-error{{initialization of 'struct A'}}
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -89,7 +89,7 @@ template struct ConstCast0<int const *, float *>; // expected-note{{instantiatio
|
|||
template<typename T, typename U>
|
||||
struct FunctionalCast1 {
|
||||
void f(T t) {
|
||||
(void)U(t); // FIXME:ugly expected-error{{operand}}
|
||||
(void)U(t); // expected-error{{C-style cast from 'struct A' to 'int'}}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -540,10 +540,10 @@ welcome!</p>
|
|||
<tr>
|
||||
<td> 5.2.3 [expr.type.conv]</td>
|
||||
<td class="complete" align="center"></td>
|
||||
<td class="complete" align="center"></td>
|
||||
<td class="basic"></td>
|
||||
<td class="medium" align="center"></td>
|
||||
<td class="advanced"></td>
|
||||
<td></td>
|
||||
<td>Only between non-class types</td>
|
||||
<td>Allows some invalid pointer conversions, AST has little information</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> 5.2.4 [expr.pseudo]</td>
|
||||
|
@ -588,10 +588,10 @@ welcome!</p>
|
|||
<tr>
|
||||
<td> 5.2.9 [expr.static.cast]</td>
|
||||
<td class="complete" align="center"></td>
|
||||
<td class="complete" align="center"></td>
|
||||
<td class="medium" align="center"></td>
|
||||
<td class="advanced" align="center"></td>
|
||||
<td></td>
|
||||
<td>Some custom conversions don't work.</td>
|
||||
<td>Allows some invalid pointer conversions, AST has little information</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> 5.2.10 [expr.reinterpret.cast]</td>
|
||||
|
@ -694,10 +694,10 @@ welcome!</p>
|
|||
<tr>
|
||||
<td> 5.4 [expr.cast]</td>
|
||||
<td class="complete" align="center"></td>
|
||||
<td class="complete" align="center"></td>
|
||||
<td class="medium"></td>
|
||||
<td class="medium" align="center"></td>
|
||||
<td class="advanced"></td>
|
||||
<td></td>
|
||||
<td>Too lenient, and may not always have correct semantics</td>
|
||||
<td>Allows some invalid pointer conversions, AST has little information</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> 5.5 [expr.mptr.oper]</td>
|
||||
|
|
Загрузка…
Ссылка в новой задаче