aboutsummaryrefslogtreecommitdiff
path: root/libcpp/lex.c
diff options
context:
space:
mode:
Diffstat (limited to 'libcpp/lex.c')
-rw-r--r--libcpp/lex.c30
1 files changed, 30 insertions, 0 deletions
diff --git a/libcpp/lex.c b/libcpp/lex.c
index 8af09e5..a8dc3ba 100644
--- a/libcpp/lex.c
+++ b/libcpp/lex.c
@@ -1352,6 +1352,28 @@ forms_identifier_p (cpp_reader *pfile, int first,
return false;
}
+/* Helper function to issue error about improper __VA_OPT__ use. */
+static void
+maybe_va_opt_error (cpp_reader *pfile)
+{
+ if (CPP_PEDANTIC (pfile) && !CPP_OPTION (pfile, va_opt))
+ {
+ /* __VA_OPT__ should not be accepted at all, but allow it in
+ system headers. */
+ if (!cpp_in_system_header (pfile))
+ cpp_error (pfile, CPP_DL_PEDWARN,
+ "__VA_OPT__ is not available until C++2a");
+ }
+ else if (!pfile->state.va_args_ok)
+ {
+ /* __VA_OPT__ should only appear in the replacement list of a
+ variadic macro. */
+ cpp_error (pfile, CPP_DL_PEDWARN,
+ "__VA_OPT__ can only appear in the expansion"
+ " of a C++2a variadic macro");
+ }
+}
+
/* Helper function to get the cpp_hashnode of the identifier BASE. */
static cpp_hashnode *
lex_identifier_intern (cpp_reader *pfile, const uchar *base)
@@ -1396,6 +1418,9 @@ lex_identifier_intern (cpp_reader *pfile, const uchar *base)
" of a C99 variadic macro");
}
+ if (result == pfile->spec_nodes.n__VA_OPT__)
+ maybe_va_opt_error (pfile);
+
/* For -Wc++-compat, warn about use of C++ named operators. */
if (result->flags & NODE_WARN_OPERATOR)
cpp_warning (pfile, CPP_W_CXX_OPERATOR_NAMES,
@@ -1485,6 +1510,11 @@ lex_identifier (cpp_reader *pfile, const uchar *base, bool starts_ucn,
" of a C99 variadic macro");
}
+ /* __VA_OPT__ should only appear in the replacement list of a
+ variadic macro. */
+ if (result == pfile->spec_nodes.n__VA_OPT__)
+ maybe_va_opt_error (pfile);
+
/* For -Wc++-compat, warn about use of C++ named operators. */
if (result->flags & NODE_WARN_OPERATOR)
cpp_warning (pfile, CPP_W_CXX_OPERATOR_NAMES,