sizeof(void) etc. should be a hard error in C++.

PR16872.

llvm-svn: 188324
This commit is contained in:
Eli Friedman 2013-08-13 22:26:42 +00:00
parent 76ff1d915c
commit 4e28b26589
10 changed files with 36 additions and 11 deletions

View File

@ -4153,6 +4153,9 @@ def ext_sizeof_alignof_void_type : Extension<
def err_sizeof_alignof_incomplete_type : Error<
"invalid application of '%select{sizeof|alignof|vec_step}0' to an "
"incomplete type %1">;
def err_sizeof_alignof_function_type : Error<
"invalid application of '%select{sizeof|alignof|vec_step}0' to a "
"function type">;
def err_sizeof_alignof_bitfield : Error<
"invalid application of '%select{sizeof|alignof}0' to bit-field">;
def err_alignof_member_of_incomplete_type : Error<

View File

@ -3176,6 +3176,10 @@ static bool CheckExtensionTraitOperandType(Sema &S, QualType T,
SourceLocation Loc,
SourceRange ArgRange,
UnaryExprOrTypeTrait TraitKind) {
// Invalid types must be hard errors for SFINAE in C++.
if (S.LangOpts.CPlusPlus)
return true;
// C99 6.5.3.4p1:
if (T->isFunctionType() &&
(TraitKind == UETT_SizeOf || TraitKind == UETT_AlignOf)) {
@ -3258,6 +3262,12 @@ bool Sema::CheckUnaryExprOrTypeTraitOperand(Expr *E,
ExprTy = E->getType();
assert(!ExprTy->isReferenceType());
if (ExprTy->isFunctionType()) {
Diag(E->getExprLoc(), diag::err_sizeof_alignof_function_type)
<< ExprKind << E->getSourceRange();
return true;
}
if (CheckObjCTraitOperandConstraints(*this, ExprTy, E->getExprLoc(),
E->getSourceRange(), ExprKind))
return true;
@ -3331,6 +3341,12 @@ bool Sema::CheckUnaryExprOrTypeTraitOperand(QualType ExprType,
ExprKind, ExprRange))
return true;
if (ExprType->isFunctionType()) {
Diag(OpLoc, diag::err_sizeof_alignof_function_type)
<< ExprKind << ExprRange;
return true;
}
if (CheckObjCTraitOperandConstraints(*this, ExprType, OpLoc, ExprRange,
ExprKind))
return true;

View File

@ -38,7 +38,7 @@ namespace PR11131 {
S &getS();
void f(...);
int f(...);
void g() {
(void)sizeof(f(getS()));

View File

@ -15,7 +15,7 @@ struct P {
};
void unevaluated_operand(P &p, int i) {
int i2 = sizeof([]()->void{}()); // expected-error{{lambda expression in an unevaluated operand}}
int i2 = sizeof([] ()->int { return 0; }()); // expected-error{{lambda expression in an unevaluated operand}}
const std::type_info &ti1 = typeid([&]() -> P& { return p; }());
const std::type_info &ti2 = typeid([&]() -> int { return i; }()); // expected-error{{lambda expression in an unevaluated operand}}
}

View File

@ -18,3 +18,11 @@ void test(A *a) {
x = sizeof(a->bitX = 3); // expected-error {{invalid application of 'sizeof' to bit-field}}
x = sizeof(a->bitY += 3); // expected-error {{invalid application of 'sizeof' to bit-field}}
}
void test2() {
int x;
x = sizeof(void); // expected-error {{invalid application of 'sizeof' to an incomplete type 'void'}}
x = sizeof(int()); // expected-error {{invalid application of 'sizeof' to a function type}}
x = sizeof(test2()); // expected-error {{invalid application of 'sizeof' to an incomplete type 'void'}}
x = sizeof(test2); // expected-error {{invalid application of 'sizeof' to a function type}}
}

View File

@ -10,8 +10,8 @@ void test() {
static_assert(sizeof(char&) == 1, "bad size");
}
void f(); // expected-note{{possible target for call}}
void f(int); // expected-note{{possible target for call}}
int f(); // expected-note{{possible target for call}}
int f(int); // expected-note{{possible target for call}}
void g() {
sizeof(&f); // expected-error{{reference to overloaded function could not be resolved; did you mean to call it with no arguments?}} \
// expected-warning{{expression result unused}}

View File

@ -44,4 +44,4 @@ static_assert(alignof(align_class_temp_pack_type<short, int, long>) == alignof(l
static_assert(alignof(align_class_temp_pack_expr<8, 16, 32>) == 32, "template's alignment is wrong");
static_assert(alignof(outer<int,char>::inner<double,short>) == alignof(int) * alignof(double), "template's alignment is wrong");
static_assert(alignof(int(int)) >= 1, "alignof(function) not positive"); // expected-warning{{invalid application of 'alignof' to a function type}}
static_assert(alignof(int(int)) >= 1, "alignof(function) not positive"); // expected-error{{invalid application of 'alignof' to a function type}}

View File

@ -44,9 +44,7 @@ S4<int(1)> y; // expected-error{{must be a type}}
void foo5()
{
(void)sizeof(int(1)); //expression
// FIXME: should we make this an error rather than a warning?
// (It affects SFINAE)
(void)sizeof(int()); // expected-warning{{function type}}
(void)sizeof(int()); // expected-error{{function type}}
}
// [dcl.ambig.res]p6:

View File

@ -201,8 +201,8 @@ namespace NoInstantiationWhenSelectingOverload {
int n;
};
void f(S);
void f(int);
int f(S);
int f(int);
void g() { f(0); }
void h() { (void)sizeof(f(0)); }

View File

@ -33,7 +33,7 @@ int main()
oneT<int>; // expected-warning {{expression result unused}}
twoT<int>; // expected-error {{reference to overloaded function could not be resolved; did you mean to call it?}}
typeid(oneT<int>); // expected-warning{{expression result unused}}
sizeof(oneT<int>); // expected-warning {{expression result unused}}
sizeof(oneT<int>); // expected-error {{invalid application of 'sizeof' to a function type}}
sizeof(twoT<int>); //expected-error {{reference to overloaded function could not be resolved; did you mean to call it?}}
decltype(oneT<int>)* fun = 0;