aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/c-family/c-common.h1
-rw-r--r--gcc/c-family/c-cppbuiltin.cc13
-rw-r--r--gcc/c-family/known-headers.cc28
-rw-r--r--gcc/c-family/known-headers.h15
-rw-r--r--gcc/c/c-decl.cc11
-rw-r--r--gcc/cp/name-lookup.cc11
-rw-r--r--gcc/testsuite/c-c++-common/spellcheck-missing-option.c15
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 } */
+}