diff options
-rw-r--r-- | gcc/c-family/c-common.h | 1 | ||||
-rw-r--r-- | gcc/c-family/c-cppbuiltin.cc | 13 | ||||
-rw-r--r-- | gcc/c-family/known-headers.cc | 28 | ||||
-rw-r--r-- | gcc/c-family/known-headers.h | 15 | ||||
-rw-r--r-- | gcc/c/c-decl.cc | 11 | ||||
-rw-r--r-- | gcc/cp/name-lookup.cc | 11 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/spellcheck-missing-option.c | 15 |
7 files changed, 94 insertions, 0 deletions
diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h index a323982..7834e0d 100644 --- a/gcc/c-family/c-common.h +++ b/gcc/c-family/c-common.h @@ -1260,6 +1260,7 @@ extern void c_stddef_cpp_builtins (void); extern void fe_file_change (const line_map_ordinary *); extern void c_parse_error (const char *, enum cpp_ttype, tree, unsigned char, rich_location *richloc); +extern diagnostic_option_id get_option_for_builtin_define (const char *macro_name); /* In c-ppoutput.cc */ extern void init_pp_output (FILE *); diff --git a/gcc/c-family/c-cppbuiltin.cc b/gcc/c-family/c-cppbuiltin.cc index 8fbfef5..c354c79 100644 --- a/gcc/c-family/c-cppbuiltin.cc +++ b/gcc/c-family/c-cppbuiltin.cc @@ -1673,6 +1673,19 @@ c_cpp_builtins (cpp_reader *pfile) cpp_define (pfile, "__DECIMAL_BID_FORMAT__"); } +/* Given NAME, return the command-line option that would make it be + a builtin define, or 0 if unrecognized. */ + +diagnostic_option_id +get_option_for_builtin_define (const char *name) +{ + if (!strcmp (name, "_OPENACC")) + return OPT_fopenacc; + if (!strcmp (name, "_OPENMP")) + return OPT_fopenmp; + return 0; +} + /* Pass an object-like macro. If it doesn't lie in the user's namespace, defines it unconditionally. Otherwise define a version with two leading underscores, and another version with two leading diff --git a/gcc/c-family/known-headers.cc b/gcc/c-family/known-headers.cc index 58a7259..2077cab 100644 --- a/gcc/c-family/known-headers.cc +++ b/gcc/c-family/known-headers.cc @@ -24,6 +24,7 @@ along with GCC; see the file COPYING3. If not see #include "c-family/name-hint.h" #include "c-family/known-headers.h" #include "gcc-rich-location.h" +#include "opts.h" /* An enum for distinguishing between the C and C++ stdlibs. */ @@ -323,3 +324,30 @@ suggest_missing_header::~suggest_missing_header () " this is probably fixable by adding %<#include %s%>", m_name_str, m_header_hint, m_header_hint); } + +/* Implementation of class suggest_missing_option. */ + +/* suggest_missing_option's ctor. */ + +suggest_missing_option::suggest_missing_option (location_t loc, + const char *macro_name, + diagnostic_option_id option_id) +: deferred_diagnostic (loc), m_name_str (macro_name), m_option_id (option_id) +{ + gcc_assert (macro_name); + gcc_assert (option_id.m_idx > 0); +} + +/* suggest_missing_option's dtor. */ + +suggest_missing_option::~suggest_missing_option () +{ + if (is_suppressed_p ()) + return; + + const char *option_name = cl_options[m_option_id.m_idx].opt_text; + inform (get_location (), + "%qs is defined when using option %qs;" + " this is probably fixable by adding %qs to the command-line options", + m_name_str, option_name, option_name); +} diff --git a/gcc/c-family/known-headers.h b/gcc/c-family/known-headers.h index 7c7ee78..a6cbbd2 100644 --- a/gcc/c-family/known-headers.h +++ b/gcc/c-family/known-headers.h @@ -41,4 +41,19 @@ class suggest_missing_header : public deferred_diagnostic const char *m_header_hint; }; +/* Subclass of deferred_diagnostic for suggesting to the user + that they have missed a command-line option. */ + +class suggest_missing_option : public deferred_diagnostic +{ + public: + suggest_missing_option (location_t loc, const char *name, + diagnostic_option_id option_id); + ~suggest_missing_option (); + + private: + const char *m_name_str; + diagnostic_option_id m_option_id; +}; + #endif /* GCC_KNOWN_HEADERS_H */ diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc index b9c688e..1c11c21 100644 --- a/gcc/c/c-decl.cc +++ b/gcc/c/c-decl.cc @@ -4547,6 +4547,17 @@ lookup_name_fuzzy (tree name, enum lookup_name_fuzzy_kind kind, location_t loc) IDENTIFIER_POINTER (name), header_hint)); + /* Next, look for exact matches for builtin defines that would have been + defined if the user had passed a command-line option (e.g. -fopenmp + for "_OPENMP"). */ + diagnostic_option_id option_id + = get_option_for_builtin_define (IDENTIFIER_POINTER (name)); + if (option_id.m_idx > 0) + return name_hint (nullptr, + new suggest_missing_option (loc, + IDENTIFIER_POINTER (name), + option_id)); + /* Only suggest names reserved for the implementation if NAME begins with an underscore. */ bool consider_implementation_names = (IDENTIFIER_POINTER (name)[0] == '_'); diff --git a/gcc/cp/name-lookup.cc b/gcc/cp/name-lookup.cc index 30dfbfe..73d2662 100644 --- a/gcc/cp/name-lookup.cc +++ b/gcc/cp/name-lookup.cc @@ -7179,6 +7179,17 @@ suggest_alternatives_for_1 (location_t location, tree name, return hint; } + /* Look for exact matches for builtin defines that would have been + defined if the user had passed a command-line option (e.g. -fopenmp + for "_OPENMP"). */ + diagnostic_option_id option_id + = get_option_for_builtin_define (IDENTIFIER_POINTER (name)); + if (option_id.m_idx > 0) + return name_hint (nullptr, + new suggest_missing_option (location, + IDENTIFIER_POINTER (name), + option_id)); + /* Otherwise, consider misspellings. */ if (!suggest_misspellings) return name_hint (); diff --git a/gcc/testsuite/c-c++-common/spellcheck-missing-option.c b/gcc/testsuite/c-c++-common/spellcheck-missing-option.c new file mode 100644 index 0000000..d7dbb2e --- /dev/null +++ b/gcc/testsuite/c-c++-common/spellcheck-missing-option.c @@ -0,0 +1,15 @@ +void +test_fopenacc () +{ + __builtin_printf ("_OPENACC = %d\n", _OPENACC); /* { dg-error "'_OPENACC' undeclared" "" { target c } } */ + /* { dg-error "'_OPENACC' was not declared in this scope" "" { target c++ } .-1 } */ + /* { dg-message "'_OPENACC' is defined when using option '-fopenacc'" "" { target *-*-* } .-2 } */ +} + +void +test_fopenmp () +{ + __builtin_printf ("_OPENMP = %d\n", _OPENMP); /* { dg-error "'_OPENMP' undeclared" "" { target c } } */ + /* { dg-error "'_OPENMP' was not declared in this scope" "" { target c++ } .-1 } */ + /* { dg-message "'_OPENMP' is defined when using option '-fopenmp'" "" { target *-*-* } .-2 } */ +} |