forked from OSchip/llvm-project
Suggest typo corrections for implicit function declarations.
A mistyped function call becomes an inmplicit function declaration in C. Suggest typo correction when one can be found. llvm-svn: 145930
This commit is contained in:
parent
83320e03e6
commit
2fb8b91f6f
|
@ -141,6 +141,7 @@ def warn_implicit_function_decl : Warning<
|
|||
def ext_implicit_function_decl : ExtWarn<
|
||||
"implicit declaration of function %0 is invalid in C99">,
|
||||
InGroup<ImplicitFunctionDeclare>;
|
||||
def note_function_suggestion : Note<"did you mean %0?">;
|
||||
|
||||
def err_ellipsis_first_arg : Error<
|
||||
"ISO C requires a named argument before '...'">;
|
||||
|
@ -272,7 +273,7 @@ def warn_redecl_library_builtin : Warning<
|
|||
def err_builtin_definition : Error<"definition of builtin function %0">;
|
||||
def err_types_compatible_p_in_cplusplus : Error<
|
||||
"__builtin_types_compatible_p is not valid in C++">;
|
||||
def warn_builtin_unknown : Warning<"use of unknown builtin %0">, DefaultError;
|
||||
def err_builtin_unknown : Error<"use of unknown builtin %0">;
|
||||
def warn_dyn_class_memaccess : Warning<
|
||||
"%select{destination for|source of|first operand of|second operand of}0 this "
|
||||
"%1 call is a pointer to dynamic class %2; vtable pointer will be "
|
||||
|
|
|
@ -7262,14 +7262,38 @@ NamedDecl *Sema::ImplicitlyDefineFunction(SourceLocation Loc,
|
|||
return Pos->second;
|
||||
}
|
||||
|
||||
// See if we can find a typo correction.
|
||||
TypoCorrection Corrected;
|
||||
FunctionDecl *Func = 0;
|
||||
std::string CorrectedStr;
|
||||
std::string CorrectedQuotedStr;
|
||||
if (S && (Corrected = CorrectTypo(DeclarationNameInfo(&II, Loc),
|
||||
LookupOrdinaryName, S, 0))) {
|
||||
// Since this is an implicit function declaration, we are only
|
||||
// interested in a potential typo for a function name.
|
||||
if ((Func = dyn_cast_or_null<FunctionDecl>(
|
||||
Corrected.getCorrectionDecl()))) {
|
||||
CorrectedStr = Corrected.getAsString(getLangOptions());
|
||||
CorrectedQuotedStr = Corrected.getQuoted(getLangOptions());
|
||||
}
|
||||
}
|
||||
|
||||
// Extension in C99. Legal in C90, but warn about it.
|
||||
if (II.getName().startswith("__builtin_"))
|
||||
Diag(Loc, diag::warn_builtin_unknown) << &II;
|
||||
Diag(Loc, diag::err_builtin_unknown) << &II;
|
||||
else if (getLangOptions().C99)
|
||||
Diag(Loc, diag::ext_implicit_function_decl) << &II;
|
||||
else
|
||||
Diag(Loc, diag::warn_implicit_function_decl) << &II;
|
||||
|
||||
if (Func) {
|
||||
// If we found a typo correction, then suggest that.
|
||||
Diag(Loc, diag::note_function_suggestion) << CorrectedQuotedStr
|
||||
<< FixItHint::CreateReplacement(Loc, CorrectedStr);
|
||||
if (Func->getLocation().isValid() && !II.getName().startswith("__builtin_"))
|
||||
Diag(Func->getLocation(), diag::note_previous_decl) << CorrectedQuotedStr;
|
||||
}
|
||||
|
||||
// Set a Declarator for the implicit definition: int foo();
|
||||
const char *Dummy;
|
||||
AttributeFactory attrFactory;
|
||||
|
|
|
@ -17,7 +17,7 @@ This test serves two purposes:
|
|||
|
||||
The list of warnings below should NEVER grow. It should gradually shrink to 0.
|
||||
|
||||
CHECK: Warnings without flags (272):
|
||||
CHECK: Warnings without flags (271):
|
||||
CHECK-NEXT: ext_anon_param_requires_type_specifier
|
||||
CHECK-NEXT: ext_anonymous_struct_union_qualified
|
||||
CHECK-NEXT: ext_array_init_copy
|
||||
|
@ -128,7 +128,6 @@ CHECK-NEXT: warn_bad_receiver_type
|
|||
CHECK-NEXT: warn_bitfield_width_exceeds_type_size
|
||||
CHECK-NEXT: warn_bool_switch_condition
|
||||
CHECK-NEXT: warn_braces_around_scalar_init
|
||||
CHECK-NEXT: warn_builtin_unknown
|
||||
CHECK-NEXT: warn_c_kext
|
||||
CHECK-NEXT: warn_call_to_pure_virtual_member_function_from_ctor_dtor
|
||||
CHECK-NEXT: warn_call_wrong_number_of_arguments
|
||||
|
|
|
@ -78,7 +78,8 @@ void test12(void) {
|
|||
}
|
||||
|
||||
void test_unknown_builtin(int a, int b) {
|
||||
__builtin_foo(a, b); // expected-error{{use of unknown builtin}}
|
||||
__builtin_isles(a, b); // expected-error{{use of unknown builtin}} \
|
||||
// expected-note{{did you mean '__builtin_isless'?}}
|
||||
}
|
||||
|
||||
int test13() {
|
||||
|
@ -101,4 +102,3 @@ int test16() {
|
|||
return __builtin_constant_p() + // expected-error{{too few arguments}}
|
||||
__builtin_constant_p(1, 2); // expected-error {{too many arguments}}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* RUN: %clang_cc1 %s -std=c89 -pedantic -fsyntax-only -verify
|
||||
/* RUN: %clang_cc1 %s -std=c89 -pedantic -fsyntax-only -verify -Wimplicit-function-declaration
|
||||
*/
|
||||
void test1() {
|
||||
{
|
||||
|
@ -82,3 +82,10 @@ void test13b() {
|
|||
int test14() { return (&*test14)(); }
|
||||
|
||||
int test15[5] = { [2] = 1 }; /* expected-warning {{designated initializers are a C99 feature}} */
|
||||
|
||||
extern int printf(__const char *__restrict __format, ...); /* expected-note{{'printf' declared here}} */
|
||||
|
||||
void test16() {
|
||||
printg("Hello, world!\n"); /* expected-warning {{implicit declaration of function 'printg'}}
|
||||
expected-note {{did you mean 'printf'?}} */
|
||||
}
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
typedef int int32_t;
|
||||
typedef unsigned char Boolean;
|
||||
|
||||
extern int printf(__const char *__restrict __format, ...); // expected-note{{'printf' declared here}}
|
||||
|
||||
void func() {
|
||||
int32_t *vector[16];
|
||||
const char compDesc[16 + 1];
|
||||
|
@ -10,8 +12,13 @@ void func() {
|
|||
if (_CFCalendarDecomposeAbsoluteTimeV(compDesc, vector, compCount)) { // expected-note {{previous implicit declaration is here}} \
|
||||
expected-warning {{implicit declaration of function '_CFCalendarDecomposeAbsoluteTimeV' is invalid in C99}}
|
||||
}
|
||||
|
||||
printg("Hello, World!\n"); // expected-warning{{implicit declaration of function 'printg' is invalid in C99}} \
|
||||
// expected-note{{did you mean 'printf'?}}
|
||||
|
||||
__builtin_is_les(1, 3); // expected-error{{use of unknown builtin '__builtin_is_les'}} \
|
||||
// expected-note{did you mean '__builtin_is_less'?}}
|
||||
}
|
||||
Boolean _CFCalendarDecomposeAbsoluteTimeV(const char *componentDesc, int32_t **vector, int32_t count) { // expected-error{{conflicting types for '_CFCalendarDecomposeAbsoluteTimeV'}}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue