зеркало из https://github.com/microsoft/clang-1.git
Properly diagnose using abstract and incomplete types in va_arg
- Move a test from test/SemaTemplate/instantiate-expr-3.cpp, it did not belong there - Incomplete and abstract types are considered hard errors git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@132979 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
2eccb67279
Коммит
0adde128d9
|
@ -3927,12 +3927,17 @@ def err_switch_incomplete_class_type : Error<
|
|||
"switch condition has incomplete class type %0">;
|
||||
def warn_empty_if_body : Warning<
|
||||
"if statement has empty body">, InGroup<EmptyBody>;
|
||||
|
||||
def err_va_start_used_in_non_variadic_function : Error<
|
||||
"'va_start' used in function with fixed args">;
|
||||
def warn_second_parameter_of_va_start_not_last_named_argument : Warning<
|
||||
"second parameter of 'va_start' not last named argument">;
|
||||
def err_first_argument_to_va_arg_not_of_type_va_list : Error<
|
||||
"first argument to 'va_arg' is of type %0 and not 'va_list'">;
|
||||
def err_second_parameter_to_va_arg_incomplete: Error<
|
||||
"second argument to 'va_arg' is of incomplete type %0">;
|
||||
def err_second_parameter_to_va_arg_abstract: Error<
|
||||
"second argument to 'va_arg' is of abstract type %0">;
|
||||
def warn_second_parameter_to_va_arg_not_pod : Warning<
|
||||
"second argument to 'va_arg' is of non-POD type %0">,
|
||||
InGroup<DiagGroup<"non-pod-varargs">>, DefaultError;
|
||||
|
|
|
@ -9818,12 +9818,24 @@ ExprResult Sema::BuildVAArgExpr(SourceLocation BuiltinLoc,
|
|||
<< OrigExpr->getType() << E->getSourceRange());
|
||||
}
|
||||
|
||||
// FIXME: Check that type is complete/non-abstract
|
||||
if (!TInfo->getType()->isDependentType()) {
|
||||
if (RequireCompleteType(TInfo->getTypeLoc().getBeginLoc(), TInfo->getType(),
|
||||
PDiag(diag::err_second_parameter_to_va_arg_incomplete)
|
||||
<< TInfo->getTypeLoc().getSourceRange()))
|
||||
return ExprError();
|
||||
|
||||
if (!TInfo->getType()->isDependentType() && !TInfo->getType()->isPODType())
|
||||
return ExprError(Diag(TInfo->getTypeLoc().getBeginLoc(),
|
||||
diag::warn_second_parameter_to_va_arg_not_pod)
|
||||
<< TInfo->getType() << TInfo->getTypeLoc().getSourceRange());
|
||||
if (RequireNonAbstractType(TInfo->getTypeLoc().getBeginLoc(),
|
||||
TInfo->getType(),
|
||||
PDiag(diag::err_second_parameter_to_va_arg_abstract)
|
||||
<< TInfo->getTypeLoc().getSourceRange()))
|
||||
return ExprError();
|
||||
|
||||
if (!TInfo->getType()->isPODType())
|
||||
Diag(TInfo->getTypeLoc().getBeginLoc(),
|
||||
diag::warn_second_parameter_to_va_arg_not_pod)
|
||||
<< TInfo->getType()
|
||||
<< TInfo->getTypeLoc().getSourceRange();
|
||||
}
|
||||
|
||||
QualType T = TInfo->getType().getNonLValueExprType(Context);
|
||||
return Owned(new (Context) VAArgExpr(BuiltinLoc, E, TInfo, RPLoc, T));
|
||||
|
|
|
@ -61,3 +61,9 @@ void f7(int a, ...) {
|
|||
__builtin_va_end(ap);
|
||||
}
|
||||
|
||||
void f8(int a, ...) {
|
||||
__builtin_va_list ap;
|
||||
__builtin_va_start(ap, a);
|
||||
(void)__builtin_va_arg(ap, void); // expected-error {{second argument to 'va_arg' is of incomplete type 'void'}}
|
||||
__builtin_va_end(ap);
|
||||
}
|
||||
|
|
|
@ -101,3 +101,21 @@ void t6(Foo somearg, ... ) {
|
|||
__builtin_va_start(list, somearg);
|
||||
}
|
||||
|
||||
void t7(int n, ...) {
|
||||
__builtin_va_list list;
|
||||
__builtin_va_start(list, n);
|
||||
(void)__builtin_va_arg(list, C); // expected-warning{{second argument to 'va_arg' is of non-POD type 'C'}}
|
||||
__builtin_va_end(list);
|
||||
}
|
||||
|
||||
struct Abstract {
|
||||
virtual void doit() = 0; // expected-note{{unimplemented pure virtual method}}
|
||||
};
|
||||
|
||||
void t8(int n, ...) {
|
||||
__builtin_va_list list;
|
||||
__builtin_va_start(list, n);
|
||||
(void)__builtin_va_arg(list, Abstract); // expected-error{{second argument to 'va_arg' is of abstract type 'Abstract'}}
|
||||
__builtin_va_end(list);
|
||||
}
|
||||
|
||||
|
|
|
@ -117,12 +117,3 @@ struct VaArg1 {
|
|||
|
||||
template struct VaArg1<__builtin_va_list, int>;
|
||||
template struct VaArg1<int, int>; // expected-note{{instantiation}}
|
||||
|
||||
struct VaArg2 {
|
||||
virtual void f(int n, ...) {
|
||||
__builtin_va_list va;
|
||||
__builtin_va_start(va, n);
|
||||
(void)__builtin_va_arg(va, VaArg2); // expected-error {{second argument to 'va_arg' is of non-POD type 'VaArg2'}}
|
||||
__builtin_va_end(va);
|
||||
}
|
||||
};
|
||||
|
|
Загрузка…
Ссылка в новой задаче