diff options
author | Hans Wennborg <hans@hanshq.net> | 2011-12-06 09:46:12 +0000 |
---|---|---|
committer | Hans Wennborg <hans@hanshq.net> | 2011-12-06 09:46:12 +0000 |
commit | 122de3e131a6902d22c97471520ec9005cca6f03 (patch) | |
tree | e7a6ee7ebd0d081839ec5a5d20dfb1dce33217af | |
parent | d64251fd56577dd5c78903454632361e094c6dc1 (diff) |
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.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@145930 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/Basic/DiagnosticSemaKinds.td | 3 | ||||
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 26 | ||||
-rw-r--r-- | test/Misc/warning-flags.c | 3 | ||||
-rw-r--r-- | test/Sema/builtins.c | 4 | ||||
-rw-r--r-- | test/Sema/c89.c | 9 | ||||
-rw-r--r-- | test/Sema/implicit-decl.c | 9 |
6 files changed, 46 insertions, 8 deletions
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 76051f7b64..2031d068a3 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -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 " diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index c90b7492a2..cc8ec878cc 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -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; diff --git a/test/Misc/warning-flags.c b/test/Misc/warning-flags.c index 04a2fde860..d384bb5d53 100644 --- a/test/Misc/warning-flags.c +++ b/test/Misc/warning-flags.c @@ -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 diff --git a/test/Sema/builtins.c b/test/Sema/builtins.c index 64efefc7fd..0850cc4ee4 100644 --- a/test/Sema/builtins.c +++ b/test/Sema/builtins.c @@ -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}} } - diff --git a/test/Sema/c89.c b/test/Sema/c89.c index 670dd15539..e4cdc11be1 100644 --- a/test/Sema/c89.c +++ b/test/Sema/c89.c @@ -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'?}} */ +} diff --git a/test/Sema/implicit-decl.c b/test/Sema/implicit-decl.c index f455977536..72e42e05bb 100644 --- a/test/Sema/implicit-decl.c +++ b/test/Sema/implicit-decl.c @@ -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; } - |