2015-12-22  Jason Merrill  <jason@redhat.com>
 
+       PR c++/67257
+       * parser.c (cp_parser_single_declaration): Reject a class template
+       that also declares a variable.
+
        PR c++/67339
        * parser.c (cp_parser_elaborated_type_specifier): Use CLASS_TYPE_P
        rather than check for RECORD_TYPE.
 
   /* Check for the declaration of a template class.  */
   if (declares_class_or_enum)
     {
-      if (cp_parser_declares_only_class_p (parser))
+      if (cp_parser_declares_only_class_p (parser)
+         || (declares_class_or_enum & 2))
        {
          // If this is a declaration, but not a definition, associate
          // any constraints with the type declaration. Constraints
 
          /* Perform access checks for template parameters.  */
          cp_parser_perform_template_parameter_access_checks (checks);
+
+         /* Give a helpful diagnostic for
+              template <class T> struct A { } a;
+            if we aren't already recovering from an error.  */
+         if (!cp_parser_declares_only_class_p (parser)
+             && !seen_error ())
+           {
+             error_at (cp_lexer_peek_token (parser->lexer)->location,
+                       "a class template declaration must not declare "
+                       "anything else");
+             cp_parser_skip_to_end_of_block_or_statement (parser);
+             goto out;
+           }
        }
     }
 
 
   enum E : int;
 };
 
-template<> enum A<>::E : int {}  // { dg-error "wrong number|expected" }
+template<> enum A<>::E : int {}  // { dg-error "wrong number" }
+
+// { dg-prune-output "expected" }
+// { dg-prune-output "specialization" }
 
--- /dev/null
+// PR c++/67257
+// { dg-do compile { target c++14 } }
+
+template <typename> struct plus;
+template <typename> struct A {
+  template <typename T> auto operator()(T);
+} foldl;                       // { dg-error "" }
+void foo() { foldl<plus<int>>(0); }
+
+// { dg-prune-output "not declared" }
+// { dg-prune-output "expected" }