OSDN Git Service

Fix PR c++/48656
[pf3gnuchains/gcc-fork.git] / gcc / cp / semantics.c
index 793883e..722e57f 100644 (file)
@@ -569,11 +569,6 @@ finish_goto_stmt (tree destination)
          if (error_operand_p (destination))
            return NULL_TREE;
        }
-      /* We don't inline calls to functions with computed gotos.
-        Those functions are typically up to some funny business,
-        and may be depending on the labels being at particular
-        addresses, or some such.  */
-      DECL_UNINLINABLE (current_function_decl) = 1;
     }
 
   check_goto (destination);
@@ -1840,7 +1835,7 @@ finish_stmt_expr_expr (tree expr, tree stmt_expr)
          /* It actually has a value we need to deal with.  First, force it
             to be an rvalue so that we won't need to build up a copy
             constructor call later when we try to assign it to something.  */
-         expr = force_rvalue (expr);
+         expr = force_rvalue (expr, tf_warning_or_error);
          if (error_operand_p (expr))
            return error_mark_node;
 
@@ -1897,7 +1892,7 @@ finish_stmt_expr (tree stmt_expr, bool has_no_scope)
         temporary object created by the final expression is destroyed at
         the end of the full-expression containing the
         statement-expression.  */
-      result = force_target_expr (type, result);
+      result = force_target_expr (type, result, tf_warning_or_error);
     }
 
   return result;
@@ -2044,7 +2039,8 @@ finish_call_expr (tree fn, VEC(tree,gc) **args, bool disallow_virtual,
             is not included in *ARGS even though it is considered to
             be part of the list of arguments.  Note that this is
             related to CWG issues 515 and 1005.  */
-         || ((TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE)
+         || (((TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE)
+              || BASELINK_P (fn))
              && current_class_ref
              && type_dependent_expression_p (current_class_ref)))
        {
@@ -2388,6 +2384,7 @@ finish_compound_literal (tree type, tree compound_literal,
      represent class temporaries with TARGET_EXPR so we elide copies.  */
   if ((!at_function_scope_p () || CP_TYPE_CONST_P (type))
       && TREE_CODE (type) == ARRAY_TYPE
+      && !TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
       && initializer_constant_valid_p (compound_literal, type))
     {
       tree decl = create_temporary_var (type);
@@ -2411,7 +2408,7 @@ finish_compound_literal (tree type, tree compound_literal,
       return decl;
     }
   else
-    return get_target_expr (compound_literal);
+    return get_target_expr_sfinae (compound_literal, complain);
 }
 
 /* Return the declaration for the function-name variable indicated by
@@ -3370,6 +3367,44 @@ finish_typeof (tree expr)
   return type;
 }
 
+/* Implement the __underlying_type keyword: Return the underlying
+   type of TYPE, suitable for use as a type-specifier.  */
+
+tree
+finish_underlying_type (tree type)
+{
+  tree underlying_type;
+
+  if (processing_template_decl)
+    {
+      underlying_type = cxx_make_type (UNDERLYING_TYPE);
+      UNDERLYING_TYPE_TYPE (underlying_type) = type;
+      SET_TYPE_STRUCTURAL_EQUALITY (underlying_type);
+
+      return underlying_type;
+    }
+
+  complete_type (type);
+
+  if (TREE_CODE (type) != ENUMERAL_TYPE)
+    {
+      error ("%qE is not an enumeration type", type);
+      return error_mark_node;
+    }
+
+  underlying_type = ENUM_UNDERLYING_TYPE (type);
+
+  /* Fixup necessary in this case because ENUM_UNDERLYING_TYPE
+     includes TYPE_MIN_VALUE and TYPE_MAX_VALUE information.
+     See finish_enum_value_list for details.  */
+  if (!ENUM_FIXED_UNDERLYING_TYPE_P (type))
+    underlying_type
+      = c_common_type_for_mode (TYPE_MODE (underlying_type),
+                               TYPE_UNSIGNED (underlying_type));
+
+  return underlying_type;
+}
+
 /* Perform C++-specific checks for __builtin_offsetof before calling
    fold_offsetof.  */
 
@@ -5297,7 +5332,8 @@ float_const_decimal64_p (void)
 bool
 literal_type_p (tree t)
 {
-  if (SCALAR_TYPE_P (t))
+  if (SCALAR_TYPE_P (t)
+      || TREE_CODE (t) == REFERENCE_TYPE)
     return true;
   if (CLASS_TYPE_P (t))
     return CLASSTYPE_LITERAL_P (t);
@@ -5372,18 +5408,6 @@ retrieve_constexpr_fundef (tree fun)
   return (constexpr_fundef *) htab_find (constexpr_fundef_table, &fundef);
 }
 
-/* Return true if type expression T is a valid parameter type, or
-   a valid return type, of a constexpr function.  */
-
-static bool
-valid_type_in_constexpr_fundecl_p (tree t)
-{
-  return (literal_type_p (t)
-         /* FIXME we allow ref to non-literal; should change standard to
-            match, or change back if not.  */
-         || TREE_CODE (t) == REFERENCE_TYPE);
-}
-
 /* Check whether the parameter and return types of FUN are valid for a
    constexpr function, and complain if COMPLAIN.  */
 
@@ -5393,7 +5417,7 @@ is_valid_constexpr_fn (tree fun, bool complain)
   tree parm = FUNCTION_FIRST_USER_PARM (fun);
   bool ret = true;
   for (; parm != NULL; parm = TREE_CHAIN (parm))
-    if (!valid_type_in_constexpr_fundecl_p (TREE_TYPE (parm)))
+    if (!literal_type_p (TREE_TYPE (parm)))
       {
        ret = false;
        if (complain)
@@ -5404,7 +5428,7 @@ is_valid_constexpr_fn (tree fun, bool complain)
   if (!DECL_CONSTRUCTOR_P (fun))
     {
       tree rettype = TREE_TYPE (TREE_TYPE (fun));
-      if (!valid_type_in_constexpr_fundecl_p (rettype))
+      if (!literal_type_p (rettype))
        {
          ret = false;
          if (complain)
@@ -7961,7 +7985,7 @@ build_lambda_object (tree lambda_expr)
             There's normally no way to express direct-initialization
             from an element of a CONSTRUCTOR, so we build up a special
             TARGET_EXPR to bypass the usual copy-initialization.  */
-         val = force_rvalue (val);
+         val = force_rvalue (val, tf_warning_or_error);
          if (TREE_CODE (val) == TARGET_EXPR)
            TARGET_EXPR_DIRECT_INIT_P (val) = true;
        }