diff options
author | Hubert Tong <hubert.reinterpretcast@gmail.com> | 2017-05-20 00:21:55 +0000 |
---|---|---|
committer | Hubert Tong <hubert.reinterpretcast@gmail.com> | 2017-05-20 00:21:55 +0000 |
commit | 8fc48a3734e7aa94a828b63f29fab24771aa10d6 (patch) | |
tree | 3f1962ca1cce3ee81f27162928dc6974743caec0 /test/Parser | |
parent | a41b9ecc818758cf022e4cd153c3e1cc65e6f43b (diff) |
Fix valid-for-expr ellipses eaten as invalid decl
Summary:
The trial parse for declarative syntax accepts an invalid pack
declaration syntax, which is ambiguous with valid pack expansions of
expressions. This commit removes the invalid pack declaration syntax to
avoid mistaking valid pack expansions as invalid declarator components.
Additionally, the trial parse of a //template-argument-list// then needs
to handle the optional ellipsis that is part of that grammar, as opposed
to relying on the trial parse for declarators accepting stray ellipses.
Reviewers: rsmith, rcraik, aaron.ballman
Reviewed By: rsmith
Subscribers: cfe-commits
Differential Revision: https://reviews.llvm.org/D33339
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@303472 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/Parser')
-rw-r--r-- | test/Parser/cxx0x-ambig.cpp | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/test/Parser/cxx0x-ambig.cpp b/test/Parser/cxx0x-ambig.cpp index 4a1b4ad777..71d32b8f51 100644 --- a/test/Parser/cxx0x-ambig.cpp +++ b/test/Parser/cxx0x-ambig.cpp @@ -132,6 +132,32 @@ namespace ellipsis { void l(int(*...)(T)); // expected-warning {{ISO C++11 requires a parenthesized pack declaration to have a name}} void l(int(S<int>::*...)(T)); // expected-warning {{ISO C++11 requires a parenthesized pack declaration to have a name}} }; + + struct CtorSink { + template <typename ...T> constexpr CtorSink(T &&...t) { } + constexpr operator int() const { return 42; } + }; + + template <unsigned ...N> struct UnsignedTmplArgSink; + + template <typename ...T> + void foo(int x, T ...t) { + // Have a variety of cases where the syntax is technically unambiguous, but hinges on careful treatment of ellipses. + CtorSink(t ...), x; // ok, expression; expected-warning 2{{expression result unused}} + + int x0(CtorSink(t ...)); // ok, declares object x0 + int *p0 = &x0; + (void)p0; + + CtorSink x1(int(t) ..., int(x)); // ok, declares object x1 + CtorSink *p1 = &x1; + (void)p1; + + UnsignedTmplArgSink<T(CtorSink(t ...)) ...> *t0; // ok + UnsignedTmplArgSink<((T *)0, 42u) ...> **t0p = &t0; + } + + template void foo(int, int, int); // expected-note {{in instantiation of function template specialization 'ellipsis::foo<int, int>' requested here}} } namespace braced_init_list { |