PR c++/79228 - extensions hide C++14 complex literal operators
libcpp/ * expr.c (interpret_float_suffix): Ignore 'i' in C++14 and up. (interpret_int_suffix): Likewise. gcc/cp/ * parser.c (cp_parser_userdef_numeric_literal): Be helpful about 'i' in C++14 and up. From-SVN: r255335
This commit is contained in:
parent
0951904f49
commit
f2b8b8adba
10 changed files with 175 additions and 12 deletions
|
@ -1,3 +1,9 @@
|
|||
2017-12-01 Jason Merrill <jason@redhat.com>
|
||||
|
||||
PR c++/79228 - extensions hide C++14 complex literal operators
|
||||
* parser.c (cp_parser_userdef_numeric_literal): Be helpful about
|
||||
'i' in C++14 and up.
|
||||
|
||||
2017-12-01 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* parser.c (cp_parser_new): Don't clear cilk_simd_fn_info.
|
||||
|
|
|
@ -4397,11 +4397,75 @@ cp_parser_userdef_numeric_literal (cp_parser *parser)
|
|||
|
||||
release_tree_vector (args);
|
||||
|
||||
error ("unable to find numeric literal operator %qD", name);
|
||||
if (!cpp_get_options (parse_in)->ext_numeric_literals)
|
||||
inform (token->location, "use -std=gnu++11 or -fext-numeric-literals "
|
||||
/* In C++14 the standard library defines complex number suffixes that
|
||||
conflict with GNU extensions. Prefer them if <complex> is #included. */
|
||||
bool ext = cpp_get_options (parse_in)->ext_numeric_literals;
|
||||
bool i14 = (cxx_dialect > cxx11
|
||||
&& (id_equal (suffix_id, "i")
|
||||
|| id_equal (suffix_id, "if")
|
||||
|| id_equal (suffix_id, "il")));
|
||||
diagnostic_t kind = DK_ERROR;
|
||||
int opt = 0;
|
||||
|
||||
if (i14 && ext)
|
||||
{
|
||||
tree cxlit = lookup_qualified_name (std_node,
|
||||
get_identifier ("complex_literals"),
|
||||
0, false, false);
|
||||
if (cxlit == error_mark_node)
|
||||
{
|
||||
/* No <complex>, so pedwarn and use GNU semantics. */
|
||||
kind = DK_PEDWARN;
|
||||
opt = OPT_Wpedantic;
|
||||
}
|
||||
}
|
||||
|
||||
bool complained
|
||||
= emit_diagnostic (kind, input_location, opt,
|
||||
"unable to find numeric literal operator %qD", name);
|
||||
|
||||
if (!complained)
|
||||
/* Don't inform either. */;
|
||||
else if (i14)
|
||||
{
|
||||
inform (token->location, "add %<using namespace std::complex_literals%> "
|
||||
"(from <complex>) to enable the C++14 user-defined literal "
|
||||
"suffixes");
|
||||
if (ext)
|
||||
inform (token->location, "or use %<j%> instead of %<i%> for the "
|
||||
"GNU built-in suffix");
|
||||
}
|
||||
else if (!ext)
|
||||
inform (token->location, "use -fext-numeric-literals "
|
||||
"to enable more built-in suffixes");
|
||||
return error_mark_node;
|
||||
|
||||
if (kind == DK_ERROR)
|
||||
value = error_mark_node;
|
||||
else
|
||||
{
|
||||
/* Use the built-in semantics. */
|
||||
tree type;
|
||||
if (id_equal (suffix_id, "i"))
|
||||
{
|
||||
if (TREE_CODE (value) == INTEGER_CST)
|
||||
type = integer_type_node;
|
||||
else
|
||||
type = double_type_node;
|
||||
}
|
||||
else if (id_equal (suffix_id, "if"))
|
||||
type = float_type_node;
|
||||
else /* if (id_equal (suffix_id, "il")) */
|
||||
type = long_double_type_node;
|
||||
|
||||
value = build_complex (build_complex_type (type),
|
||||
fold_convert (type, integer_zero_node),
|
||||
fold_convert (type, value));
|
||||
}
|
||||
|
||||
if (cp_parser_uncommitted_to_tentative_parse_p (parser))
|
||||
/* Avoid repeated diagnostics. */
|
||||
token->u.value = value;
|
||||
return value;
|
||||
}
|
||||
|
||||
/* Parse a user-defined string constant. Returns a call to a user-defined
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
// Integer imaginary...
|
||||
|
||||
constexpr unsigned long long
|
||||
operator"" i(unsigned long long n) // { dg-warning "shadowed by implementation" }
|
||||
operator"" i(unsigned long long n) // { dg-warning "shadowed by implementation" "" { target c++11_only } }
|
||||
{ return 4 * n + 0; }
|
||||
|
||||
constexpr unsigned long long
|
||||
|
@ -22,7 +22,7 @@ operator"" J(unsigned long long n) // { dg-warning "shadowed by implementation"
|
|||
// Floating-point imaginary...
|
||||
|
||||
constexpr long double
|
||||
operator"" i(long double n) // { dg-warning "shadowed by implementation" }
|
||||
operator"" i(long double n) // { dg-warning "shadowed by implementation" "" { target c++11_only } }
|
||||
{ return 4.0L * n + 0.0L; }
|
||||
|
||||
constexpr long double
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
// Integer imaginary...
|
||||
|
||||
constexpr unsigned long long
|
||||
operator"" i(unsigned long long n) // { dg-warning "shadowed by implementation" }
|
||||
operator"" i(unsigned long long n) // { dg-warning "shadowed by implementation" "" { target c++11_only } }
|
||||
{ return 4 * n + 0; }
|
||||
|
||||
constexpr unsigned long long
|
||||
|
@ -22,7 +22,7 @@ operator"" J(unsigned long long n) // { dg-warning "shadowed by implementation"
|
|||
// Floating-point imaginary...
|
||||
|
||||
constexpr long double
|
||||
operator"" i(long double n) // { dg-warning "shadowed by implementation" }
|
||||
operator"" i(long double n) // { dg-warning "shadowed by implementation" "" { target c++11_only } }
|
||||
{ return 4.0L * n + 0.0L; }
|
||||
|
||||
constexpr long double
|
||||
|
|
10
gcc/testsuite/g++.dg/cpp1y/complex_literals1.C
Normal file
10
gcc/testsuite/g++.dg/cpp1y/complex_literals1.C
Normal file
|
@ -0,0 +1,10 @@
|
|||
// PR c++/79228
|
||||
// { dg-do compile { target c++14 } }
|
||||
|
||||
#include <complex>
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace std::complex_literals;
|
||||
auto a = std::abs(0.0i);
|
||||
}
|
11
gcc/testsuite/g++.dg/cpp1y/complex_literals1a.C
Normal file
11
gcc/testsuite/g++.dg/cpp1y/complex_literals1a.C
Normal file
|
@ -0,0 +1,11 @@
|
|||
// PR c++/79228
|
||||
// { dg-do compile { target c++14 } }
|
||||
// { dg-options "" }
|
||||
|
||||
#include <complex>
|
||||
|
||||
int main()
|
||||
{
|
||||
auto a = std::abs(0.0i); // { dg-error "literal operator" }
|
||||
// { dg-message "complex_literals" "" { target *-*-* } .-1 }
|
||||
}
|
25
gcc/testsuite/g++.dg/cpp1y/complex_literals2.C
Normal file
25
gcc/testsuite/g++.dg/cpp1y/complex_literals2.C
Normal file
|
@ -0,0 +1,25 @@
|
|||
// PR c++/79228
|
||||
// { dg-do compile { target c++14 } }
|
||||
// { dg-options "-Wpedantic" }
|
||||
|
||||
template <class,class> struct same;
|
||||
template <class T> struct same<T,T> { };
|
||||
|
||||
int main()
|
||||
{
|
||||
same<decltype(0i),__complex int>{}; // { dg-warning "literal operator" }
|
||||
// { dg-message "complex_literals" "" { target *-*-* } .-1 }
|
||||
// { dg-message "built-in" "" { target *-*-* } .-2 }
|
||||
|
||||
same<decltype(0.0i),__complex double>{}; // { dg-warning "literal operator" }
|
||||
// { dg-message "complex_literals" "" { target *-*-* } .-1 }
|
||||
// { dg-message "built-in" "" { target *-*-* } .-2 }
|
||||
|
||||
same<decltype(0.0if),__complex float>{}; // { dg-warning "literal operator" }
|
||||
// { dg-message "complex_literals" "" { target *-*-* } .-1 }
|
||||
// { dg-message "built-in" "" { target *-*-* } .-2 }
|
||||
|
||||
same<decltype(0.0il),__complex long double>{}; // { dg-warning "literal operator" }
|
||||
// { dg-message "complex_literals" "" { target *-*-* } .-1 }
|
||||
// { dg-message "built-in" "" { target *-*-* } .-2 }
|
||||
}
|
14
gcc/testsuite/g++.dg/cpp1y/complex_literals2a.C
Normal file
14
gcc/testsuite/g++.dg/cpp1y/complex_literals2a.C
Normal file
|
@ -0,0 +1,14 @@
|
|||
// PR c++/79228
|
||||
// { dg-do compile { target c++14 } }
|
||||
// { dg-options "" }
|
||||
|
||||
template <class,class> struct same;
|
||||
template <class T> struct same<T,T> { };
|
||||
|
||||
int main()
|
||||
{
|
||||
same<decltype(0i),__complex int>{};
|
||||
same<decltype(0.0i),__complex double>{};
|
||||
same<decltype(0.0if),__complex float>{};
|
||||
same<decltype(0.0il),__complex long double>{};
|
||||
}
|
|
@ -1,3 +1,9 @@
|
|||
2017-12-01 Jason Merrill <jason@redhat.com>
|
||||
|
||||
PR c++/79228 - extensions hide C++14 complex literal operators
|
||||
* expr.c (interpret_float_suffix): Ignore 'i' in C++14 and up.
|
||||
(interpret_int_suffix): Likewise.
|
||||
|
||||
2017-11-28 David Malcolm <dmalcolm@redhat.com>
|
||||
|
||||
PR c/82050
|
||||
|
|
|
@ -90,6 +90,8 @@ static cpp_num parse_has_include (cpp_reader *, enum include_type);
|
|||
static unsigned int
|
||||
interpret_float_suffix (cpp_reader *pfile, const uchar *s, size_t len)
|
||||
{
|
||||
size_t orig_len = len;
|
||||
const uchar *orig_s = s;
|
||||
size_t flags;
|
||||
size_t f, d, l, w, q, i, fn, fnx, fn_bits;
|
||||
|
||||
|
@ -269,8 +271,20 @@ interpret_float_suffix (cpp_reader *pfile, const uchar *s, size_t len)
|
|||
if (fn && fn_bits == 96)
|
||||
return 0;
|
||||
|
||||
if (i && !CPP_OPTION (pfile, ext_numeric_literals))
|
||||
return 0;
|
||||
if (i)
|
||||
{
|
||||
if (!CPP_OPTION (pfile, ext_numeric_literals))
|
||||
return 0;
|
||||
|
||||
/* In C++14 and up these suffixes are in the standard library, so treat
|
||||
them as user-defined literals. */
|
||||
if (CPP_OPTION (pfile, cplusplus)
|
||||
&& CPP_OPTION (pfile, lang) > CLK_CXX11
|
||||
&& (!memcmp (orig_s, "i", orig_len)
|
||||
|| !memcmp (orig_s, "if", orig_len)
|
||||
|| !memcmp (orig_s, "il", orig_len)))
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((w || q) && !CPP_OPTION (pfile, ext_numeric_literals))
|
||||
return 0;
|
||||
|
@ -299,6 +313,7 @@ cpp_interpret_float_suffix (cpp_reader *pfile, const char *s, size_t len)
|
|||
static unsigned int
|
||||
interpret_int_suffix (cpp_reader *pfile, const uchar *s, size_t len)
|
||||
{
|
||||
size_t orig_len = len;
|
||||
size_t u, l, i;
|
||||
|
||||
u = l = i = 0;
|
||||
|
@ -321,8 +336,20 @@ interpret_int_suffix (cpp_reader *pfile, const uchar *s, size_t len)
|
|||
if (l > 2 || u > 1 || i > 1)
|
||||
return 0;
|
||||
|
||||
if (i && !CPP_OPTION (pfile, ext_numeric_literals))
|
||||
return 0;
|
||||
if (i)
|
||||
{
|
||||
if (!CPP_OPTION (pfile, ext_numeric_literals))
|
||||
return 0;
|
||||
|
||||
/* In C++14 and up these suffixes are in the standard library, so treat
|
||||
them as user-defined literals. */
|
||||
if (CPP_OPTION (pfile, cplusplus)
|
||||
&& CPP_OPTION (pfile, lang) > CLK_CXX11
|
||||
&& (!memcmp (s, "i", orig_len)
|
||||
|| !memcmp (s, "if", orig_len)
|
||||
|| !memcmp (s, "il", orig_len)))
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ((i ? CPP_N_IMAGINARY : 0)
|
||||
| (u ? CPP_N_UNSIGNED : 0)
|
||||
|
|
Loading…
Add table
Reference in a new issue