From 222e2a7620e6520ffaf4fc4e69d79c18da31542e Mon Sep 17 00:00:00 2001 From: "Zancanaro; Carlo" Date: Mon, 24 Sep 2012 09:58:17 +1000 Subject: Add the clang library to the repo (with some of my changes, too). --- clang/test/SemaCXX/reinterpret-cast.cpp | 292 ++++++++++++++++++++++++++++++++ 1 file changed, 292 insertions(+) create mode 100644 clang/test/SemaCXX/reinterpret-cast.cpp (limited to 'clang/test/SemaCXX/reinterpret-cast.cpp') diff --git a/clang/test/SemaCXX/reinterpret-cast.cpp b/clang/test/SemaCXX/reinterpret-cast.cpp new file mode 100644 index 0000000..7f41b93 --- /dev/null +++ b/clang/test/SemaCXX/reinterpret-cast.cpp @@ -0,0 +1,292 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -ffreestanding -Wundefined-reinterpret-cast %s + +#include + +enum test { testval = 1 }; +struct structure { int m; }; +typedef void (*fnptr)(); + +// Test the conversion to self. +void self_conversion() +{ + // T->T is allowed per [expr.reinterpret.cast]p2 so long as it doesn't + // cast away constness, and is integral, enumeration, pointer or + // pointer-to-member. + int i = 0; + (void)reinterpret_cast(i); + + test e = testval; + (void)reinterpret_cast(e); + + // T*->T* is allowed + int *pi = 0; + (void)reinterpret_cast(pi); + + const int structure::*psi = 0; + (void)reinterpret_cast(psi); + + structure s; + (void)reinterpret_cast(s); // expected-error {{reinterpret_cast from 'structure' to 'structure' is not allowed}} + + float f = 0.0f; + (void)reinterpret_cast(f); // expected-error {{reinterpret_cast from 'float' to 'float' is not allowed}} +} + +// Test conversion between pointer and integral types, as in /3 and /4. +void integral_conversion() +{ + void *vp = reinterpret_cast(testval); + intptr_t i = reinterpret_cast(vp); + (void)reinterpret_cast(i); + fnptr fnp = reinterpret_cast(i); + (void)reinterpret_cast(fnp); // expected-error {{cast from pointer to smaller type 'char' loses information}} + (void)reinterpret_cast(fnp); +} + +void pointer_conversion() +{ + int *p1 = 0; + float *p2 = reinterpret_cast(p1); + structure *p3 = reinterpret_cast(p2); + typedef int **ppint; + ppint *deep = reinterpret_cast(p3); + (void)reinterpret_cast(deep); +} + +void constness() +{ + int ***const ipppc = 0; + // Valid: T1* -> T2 const* + int const *icp = reinterpret_cast(ipppc); + // Invalid: T1 const* -> T2* + (void)reinterpret_cast(icp); // expected-error {{reinterpret_cast from 'const int *' to 'int *' casts away qualifiers}} + // Invalid: T1*** -> T2 const* const** + int const *const **icpcpp = reinterpret_cast(ipppc); // expected-error {{reinterpret_cast from 'int ***' to 'const int *const **' casts away qualifiers}} + // Valid: T1* -> T2* + int *ip = reinterpret_cast(icpcpp); + // Valid: T* -> T const* + (void)reinterpret_cast(ip); + // Valid: T*** -> T2 const* const* const* + (void)reinterpret_cast(ipppc); +} + +void fnptrs() +{ + typedef int (*fnptr2)(int); + fnptr fp = 0; + (void)reinterpret_cast(fp); + void *vp = reinterpret_cast(fp); + (void)reinterpret_cast(vp); +} + +void refs() +{ + long l = 0; + char &c = reinterpret_cast(l); + // Bad: from rvalue + (void)reinterpret_cast(&c); // expected-error {{reinterpret_cast from rvalue to reference type 'int &'}} +} + +void memptrs() +{ + const int structure::*psi = 0; + (void)reinterpret_cast(psi); + (void)reinterpret_cast(psi); // expected-error {{reinterpret_cast from 'const int structure::*' to 'int structure::*' casts away qualifiers}} + + void (structure::*psf)() = 0; + (void)reinterpret_cast(psf); + + (void)reinterpret_cast(psi); // expected-error {{reinterpret_cast from 'const int structure::*' to 'void (structure::*)()' is not allowed}} + (void)reinterpret_cast(psf); // expected-error {{reinterpret_cast from 'void (structure::*)()' to 'int structure::*' is not allowed}} + + // Cannot cast from integers to member pointers, not even the null pointer + // literal. + (void)reinterpret_cast(0); // expected-error {{reinterpret_cast from 'int' to 'void (structure::*)()' is not allowed}} + (void)reinterpret_cast(0); // expected-error {{reinterpret_cast from 'int' to 'int structure::*' is not allowed}} +} + +namespace PR5545 { +// PR5545 +class A; +class B; +void (A::*a)(); +void (B::*b)() = reinterpret_cast(a); +} + +// +void const_arrays() { + typedef char STRING[10]; + const STRING *s; + const char *c; + + (void)reinterpret_cast(s); // expected-error {{reinterpret_cast from 'const STRING *' (aka 'char const (*)[10]') to 'char *' casts away qualifiers}} + (void)reinterpret_cast(c); +} + +namespace PR9564 { + struct a { int a : 10; }; a x; + int *y = &reinterpret_cast(x.a); // expected-error {{not allowed}} + + __attribute((ext_vector_type(4))) typedef float v4; + float& w(v4 &a) { return reinterpret_cast(a[1]); } // expected-error {{not allowed}} +} + +void dereference_reinterpret_cast() { + struct A {}; + typedef A A2; + class B {}; + typedef B B2; + A a; + B b; + A2 a2; + B2 b2; + long l; + double d; + float f; + char c; + unsigned char uc; + void* v_ptr; + (void)reinterpret_cast(l); // expected-warning {{reinterpret_cast from 'long' to 'double &' has undefined behavior}} + (void)*reinterpret_cast(&l); // expected-warning {{dereference of type 'double *' that was reinterpret_cast from type 'long *' has undefined behavior}} + (void)reinterpret_cast(f); // expected-warning {{reinterpret_cast from 'float' to 'double &' has undefined behavior}} + (void)*reinterpret_cast(&f); // expected-warning {{dereference of type 'double *' that was reinterpret_cast from type 'float *' has undefined behavior}} + (void)reinterpret_cast(l); // expected-warning {{reinterpret_cast from 'long' to 'float &' has undefined behavior}} + (void)*reinterpret_cast(&l); // expected-warning {{dereference of type 'float *' that was reinterpret_cast from type 'long *' has undefined behavior}} + (void)reinterpret_cast(d); // expected-warning {{reinterpret_cast from 'double' to 'float &' has undefined behavior}} + (void)*reinterpret_cast(&d); // expected-warning {{dereference of type 'float *' that was reinterpret_cast from type 'double *' has undefined behavior}} + + // TODO: add warning for tag types + (void)reinterpret_cast(b); + (void)*reinterpret_cast(&b); + (void)reinterpret_cast(a); + (void)*reinterpret_cast(&a); + (void)reinterpret_cast(b2); + (void)*reinterpret_cast(&b2); + (void)reinterpret_cast(a2); + (void)*reinterpret_cast(&a2); + + // Casting to itself is allowed + (void)reinterpret_cast(a); + (void)*reinterpret_cast(&a); + (void)reinterpret_cast(b); + (void)*reinterpret_cast(&b); + (void)reinterpret_cast(l); + (void)*reinterpret_cast(&l); + (void)reinterpret_cast(d); + (void)*reinterpret_cast(&d); + (void)reinterpret_cast(c); + (void)*reinterpret_cast(&c); + + // Casting to and from chars are allowable + (void)reinterpret_cast(c); + (void)*reinterpret_cast(&c); + (void)reinterpret_cast(c); + (void)*reinterpret_cast(&c); + (void)reinterpret_cast(c); + (void)*reinterpret_cast(&c); + (void)reinterpret_cast(c); + (void)*reinterpret_cast(&c); + (void)reinterpret_cast(l); + (void)*reinterpret_cast(&l); + (void)reinterpret_cast(d); + (void)*reinterpret_cast(&d); + (void)reinterpret_cast(f); + (void)*reinterpret_cast(&f); + + // Casting from void pointer. + (void)*reinterpret_cast(v_ptr); + (void)*reinterpret_cast(v_ptr); + (void)*reinterpret_cast(v_ptr); + (void)*reinterpret_cast(v_ptr); + (void)*reinterpret_cast(v_ptr); + + // Casting to void pointer + (void)*reinterpret_cast(&a); + (void)*reinterpret_cast(&b); + (void)*reinterpret_cast(&l); + (void)*reinterpret_cast(&d); + (void)*reinterpret_cast(&f); +} + +void reinterpret_cast_whitelist () { + // the dynamic type of the object + int a; + float b; + (void)reinterpret_cast(a); + (void)*reinterpret_cast(&a); + (void)reinterpret_cast(b); + (void)*reinterpret_cast(&b); + + // a cv-qualified version of the dynamic object + (void)reinterpret_cast(a); + (void)*reinterpret_cast(&a); + (void)reinterpret_cast(a); + (void)*reinterpret_cast(&a); + (void)reinterpret_cast(a); + (void)*reinterpret_cast(&a); + (void)reinterpret_cast(b); + (void)*reinterpret_cast(&b); + (void)reinterpret_cast(b); + (void)*reinterpret_cast(&b); + (void)reinterpret_cast(b); + (void)*reinterpret_cast(&b); + + // a type that is the signed or unsigned type corresponding to the dynamic + // type of the object + signed d; + unsigned e; + (void)reinterpret_cast(d); + (void)*reinterpret_cast(&d); + (void)reinterpret_cast(e); + (void)*reinterpret_cast(&e); + (void)reinterpret_cast(d); + (void)*reinterpret_cast(&d); + (void)reinterpret_cast(e); + (void)*reinterpret_cast(&e); + + // a type that is the signed or unsigned type corresponding a cv-qualified + // version of the dynamic type the object + (void)reinterpret_cast(d); + (void)*reinterpret_cast(&d); + (void)reinterpret_cast(e); + (void)*reinterpret_cast(&e); + (void)reinterpret_cast(d); + (void)*reinterpret_cast(&d); + (void)reinterpret_cast(e); + (void)*reinterpret_cast(&e); + (void)reinterpret_cast(d); + (void)*reinterpret_cast(&d); + (void)reinterpret_cast(e); + (void)*reinterpret_cast(&e); + (void)reinterpret_cast(d); + (void)*reinterpret_cast(&d); + (void)reinterpret_cast(e); + (void)*reinterpret_cast(&e); + (void)reinterpret_cast(d); + (void)*reinterpret_cast(&d); + (void)reinterpret_cast(e); + (void)*reinterpret_cast(&e); + (void)reinterpret_cast(d); + (void)*reinterpret_cast(&d); + (void)reinterpret_cast(e); + (void)*reinterpret_cast(&e); + + // an aggregate or union type that includes one of the aforementioned types + // among its members (including, recursively, a member of a subaggregate or + // contained union) + // TODO: checking is not implemented for tag types + + // a type that is a (possible cv-qualified) base class type of the dynamic + // type of the object + // TODO: checking is not implemented for tag types + + // a char or unsigned char type + (void)reinterpret_cast(a); + (void)*reinterpret_cast(&a); + (void)reinterpret_cast(a); + (void)*reinterpret_cast(&a); + (void)reinterpret_cast(b); + (void)*reinterpret_cast(&b); + (void)reinterpret_cast(b); + (void)*reinterpret_cast(&b); +} -- cgit v1.2.3