+2004-06-10 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/15227
+ * parser.c (cp_parser_direct_declarator): Robustify.
+
+ PR c++/15877
+ * pt.c (tsubst_copy): Use decl_constant_value on enumeration
+ constants in non-dependent contexts.
+
+ PR c++/14211
+ PR c++/15076
+ * typeck.c (build_static_cast): Wrap casts in NON_LVALUE_EXPR when
+ necessary.
+
2004-06-10 Jakub Jelinek <jakub@redhat.com>
PR c++/14791
type = resolve_typename_type (scope,
/*only_current_p=*/false);
/* If that failed, the declarator is invalid. */
- if (type != error_mark_node)
- scope = type;
+ if (type == error_mark_node)
+ error ("`%T::%D' is not a type",
+ TYPE_CONTEXT (scope),
+ TYPE_IDENTIFIER (scope));
/* Build a new DECLARATOR. */
declarator = build_nt (SCOPE_REF,
scope,
return t;
/* If ARGS is NULL, then T is known to be non-dependent. */
if (args == NULL_TREE)
- return t;
+ return decl_constant_value (t);
/* Unfortunately, we cannot just call lookup_name here.
Consider:
t. */
result = perform_direct_initialization_if_possible (type, expr);
if (result)
- return convert_from_reference (result);
+ {
+ result = convert_from_reference (result);
+ /* [expr.static.cast]
+
+ If T is a reference type, the result is an lvalue; otherwise,
+ the result is an rvalue. */
+ if (TREE_CODE (type) != REFERENCE_TYPE
+ && real_lvalue_p (result))
+ result = build1 (NON_LVALUE_EXPR, TREE_TYPE (result), result);
+ return result;
+ }
/* [expr.static.cast]
--- /dev/null
+// PR c++/14211
+
+void f(char *str) {
+ char *& m = const_cast<char *>(str); // { dg-error "" }
+}
--- /dev/null
+// PR c++/15076
+
+struct Y { Y(int &); }; // { dg-error "" }
+
+int v;
+Y y1(reinterpret_cast<int>(v)); // { dg-error "" }
--- /dev/null
+// PR c++/15877
+
+template <int n> struct T1 { enum { N = 3 }; };
+template <int n> struct T2 { enum { N = n, N1 = T1<N>::N }; };
--- /dev/null
+// PR c++/15227
+
+template<typename> struct A {};
+
+template<typename T> void A<T>::B::foo() {} // { dg-error "" }