aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMarek Polacek <polacek@redhat.com>2019-01-28 22:14:27 +0000
committerMarek Polacek <mpolacek@gcc.gnu.org>2019-01-28 22:14:27 +0000
commitb6d0f41ac5c1786911858b4763bb6f92519166f4 (patch)
treeca1b40716b10b941b960f762ca38414b38cab433 /gcc
parent2c5b39203276b00496ef32468ccb61d445aef97b (diff)
downloadgcc-b6d0f41ac5c1786911858b4763bb6f92519166f4.zip
gcc-b6d0f41ac5c1786911858b4763bb6f92519166f4.tar.gz
gcc-b6d0f41ac5c1786911858b4763bb6f92519166f4.tar.bz2
PR c++/88358 - name wrongly treated as type.
* parser.c (cp_parser_direct_declarator): Don't assume a qualified-id in parameter-list is a type if the function's declarator-id is not qualified. * g++.dg/cpp2a/typename1.C: Add dg-error. * g++.dg/cpp2a/typename13.C: New test. * g++.dg/cpp2a/typename6.C: Make a function name qualified. Add typename. From-SVN: r268343
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog7
-rw-r--r--gcc/cp/parser.c31
-rw-r--r--gcc/testsuite/ChangeLog8
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/typename1.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/typename13.C13
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/typename6.C11
6 files changed, 54 insertions, 18 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index dcac8e7..5e2f69d 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,10 @@
+2019-01-28 Marek Polacek <polacek@redhat.com>
+
+ PR c++/88358 - name wrongly treated as type.
+ * parser.c (cp_parser_direct_declarator): Don't assume a qualified-id
+ in parameter-list is a type if the function's declarator-id is not
+ qualified.
+
2019-01-27 Marek Polacek <polacek@redhat.com>
PR c++/88815 - narrowing conversion lost in decltype.
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index dc9d651..16f2a32 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -21107,23 +21107,28 @@ cp_parser_direct_declarator (cp_parser* parser,
if (cxx_dialect >= cxx2a
&& (flags & CP_PARSER_FLAGS_TYPENAME_OPTIONAL)
&& declarator->kind == cdk_id
- /* ...whose declarator-id is qualified. */
- && qualifying_scope != NULL_TREE
&& !at_class_scope_p ()
&& cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
{
- /* Now we have something like
- template <typename T> int C::x(S::p);
- which can be a function template declaration or a
- variable template definition. If name lookup for
- the declarator-id C::x finds one or more function
- templates, assume S::p to name a type. Otherwise,
- don't. */
- tree decl
- = cp_parser_lookup_name_simple (parser, unqualified_name,
- token->location);
- if (!is_overloaded_fn (decl))
+ /* ...whose declarator-id is qualified. If it isn't, never
+ assume the parameters to refer to types. */
+ if (qualifying_scope == NULL_TREE)
flags &= ~CP_PARSER_FLAGS_TYPENAME_OPTIONAL;
+ else
+ {
+ /* Now we have something like
+ template <typename T> int C::x(S::p);
+ which can be a function template declaration or a
+ variable template definition. If name lookup for
+ the declarator-id C::x finds one or more function
+ templates, assume S::p to name a type. Otherwise,
+ don't. */
+ tree decl
+ = cp_parser_lookup_name_simple (parser, unqualified_name,
+ token->location);
+ if (!is_overloaded_fn (decl))
+ flags &= ~CP_PARSER_FLAGS_TYPENAME_OPTIONAL;
+ }
}
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index a36e19c..7af76a1 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,13 @@
2019-01-28 Marek Polacek <polacek@redhat.com>
+ PR c++/88358 - name wrongly treated as type.
+ * g++.dg/cpp2a/typename1.C: Add dg-error.
+ * g++.dg/cpp2a/typename13.C: New test.
+ * g++.dg/cpp2a/typename6.C: Make a function name qualified.
+ Add typename.
+
+2019-01-28 Marek Polacek <polacek@redhat.com>
+
* g++.dg/cpp0x/enum37.C: Add dg-error.
2019-01-28 Bernd Edlinger <bernd.edlinger@hotmail.de>
diff --git a/gcc/testsuite/g++.dg/cpp2a/typename1.C b/gcc/testsuite/g++.dg/cpp2a/typename1.C
index 833d3b8..0c1f630 100644
--- a/gcc/testsuite/g++.dg/cpp2a/typename1.C
+++ b/gcc/testsuite/g++.dg/cpp2a/typename1.C
@@ -6,7 +6,7 @@ template<class T> T::R f();
// Ill-formed (no diagnostic required), attempt to declare
// a void variable template
-template<class T> void f(T::R);
+template<class T> void f(T::R); // { dg-error "declared void" }
template <class T> struct A;
template <class T> using B = A<T>::U;
diff --git a/gcc/testsuite/g++.dg/cpp2a/typename13.C b/gcc/testsuite/g++.dg/cpp2a/typename13.C
new file mode 100644
index 0000000..c439f72
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/typename13.C
@@ -0,0 +1,13 @@
+// P0634R3, PR c++/88358
+// { dg-do compile { target c++2a } }
+
+template <typename T>
+int pi(T::your_pi);
+
+struct Foo { static constexpr int your_pi = 10; };
+
+int
+main ()
+{
+ return pi<Foo>;
+}
diff --git a/gcc/testsuite/g++.dg/cpp2a/typename6.C b/gcc/testsuite/g++.dg/cpp2a/typename6.C
index 49e2235..e96e2ab 100644
--- a/gcc/testsuite/g++.dg/cpp2a/typename6.C
+++ b/gcc/testsuite/g++.dg/cpp2a/typename6.C
@@ -55,11 +55,14 @@ struct S2 {
// (5.2.4) parameter-declaration in a declarator of a function or function
// template declaration whose declarator-id is qualified,
// unless that parameter-declaration appears in a default argument
-template<typename T>
-int fn3 (T::X);
+
+struct M {
+ template<typename T>
+ int fn (T::X);
+};
template<typename T>
-int fn4 (T::X p) { return p; }
+int M::fn (T::X p) { return p; }
// (5.2.5) parameter-declaration in a lambda-declarator,
// unless that parameter-declaration appears in a default argument
@@ -92,7 +95,7 @@ struct S5 {
};
template<typename T>
-void fn7 (T::X p)
+void fn7 (typename T::X p)
{
int i = static_cast<T::Y>(p);
i = dynamic_cast<T::Y>(p);