OSDN Git Service

PR c++/37208
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 3 Sep 2008 04:10:27 +0000 (04:10 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 3 Sep 2008 04:10:27 +0000 (04:10 +0000)
        * call.c (build_over_call): Make =delete work with SFINAE.
        * class.c (resolve_address_of_overloaded_function): Likewise.

        * cp-tree.h (struct lang_decl_flags): Rename threadprivate_p to
        threadprivate_or_deleted_p.
        (CP_DECL_THREADPRIVATE_P): Adjust.
        (DECL_DELETED_FN): Likewise.
        (SD_UNINITIALIZED, SD_INITIALIZED, SD_DEFAULTED): New macros.
        (SD_DELETED): New macro.
        * parser.c (cp_parser_init_declarator): Use them.
        * decl.c (start_decl): Use them.

        * decl2.c (mark_used): Give =deleted error even in sizeof.

        * typeck2.c (check_narrowing): Downgrade narrowing error to
        permerror.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@139926 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/class.c
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/decl2.c
gcc/cp/parser.c
gcc/cp/typeck2.c
gcc/testsuite/g++.dg/cpp0x/defaulted4.C [new file with mode: 0644]

index c5ccb40..88b3946 100644 (file)
@@ -1,3 +1,23 @@
+2008-09-02  Jason Merrill  <jason@redhat.com>
+
+       PR c++/37208
+       * call.c (build_over_call): Make =delete work with SFINAE.
+       * class.c (resolve_address_of_overloaded_function): Likewise.
+
+       * cp-tree.h (struct lang_decl_flags): Rename threadprivate_p to
+       threadprivate_or_deleted_p.
+       (CP_DECL_THREADPRIVATE_P): Adjust.
+       (DECL_DELETED_FN): Likewise.
+       (SD_UNINITIALIZED, SD_INITIALIZED, SD_DEFAULTED): New macros.
+       (SD_DELETED): New macro.
+       * parser.c (cp_parser_init_declarator): Use them.
+       * decl.c (start_decl): Use them.
+
+       * decl2.c (mark_used): Give =deleted error even in sizeof.
+
+       * typeck2.c (check_narrowing): Downgrade narrowing error to
+       permerror.
+
 2008-09-02  Aldy Hernandez  <aldyh@redhat.com>
 
        * typeck.c (build_array_ref): Use new location argument.
index 571f36f..653e06e 100644 (file)
@@ -5119,6 +5119,10 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
        joust (cand, w->loser, 1);
     }
 
+  /* Make =delete work with SFINAE.  */
+  if (DECL_DELETED_FN (fn) && !(complain & tf_error))
+    return error_mark_node;
+
   if (DECL_FUNCTION_MEMBER_P (fn))
     {
       /* If FN is a template function, two cases must be considered.
index 4f69c7e..ab8391b 100644 (file)
@@ -6185,6 +6185,10 @@ resolve_address_of_overloaded_function (tree target_type,
      function will be marked as used at this point.  */
   if (!(flags & tf_conv))
     {
+      /* Make =delete work with SFINAE.  */
+      if (DECL_DELETED_FN (fn) && !(flags & tf_error))
+       return error_mark_node;
+      
       mark_used (fn);
       /* We could not check access when this expression was originally
         created since we did not know at that time to which function
index 09b3b2f..a668aa0 100644 (file)
@@ -1629,7 +1629,7 @@ struct lang_decl_flags GTY(())
   unsigned this_thunk_p : 1;
   unsigned repo_available_p : 1;
   unsigned hidden_friend_p : 1;
-  unsigned threadprivate_p : 1;
+  unsigned threadprivate_or_deleted_p : 1;
   unsigned defaulted_p : 1;
 
   union lang_decl_u {
@@ -2645,11 +2645,11 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter)
 /* Nonzero if DECL has been declared threadprivate by
    #pragma omp threadprivate.  */
 #define CP_DECL_THREADPRIVATE_P(DECL) \
-  (DECL_LANG_SPECIFIC (VAR_DECL_CHECK (DECL))->decl_flags.threadprivate_p)
+  (DECL_LANG_SPECIFIC (VAR_DECL_CHECK (DECL))->decl_flags.threadprivate_or_deleted_p)
 
 /* Nonzero if DECL was declared with '= delete'.  */
 #define DECL_DELETED_FN(DECL) \
-  (DECL_LANG_SPECIFIC (FUNCTION_DECL_CHECK (DECL))->decl_flags.threadprivate_p)
+  (DECL_LANG_SPECIFIC (FUNCTION_DECL_CHECK (DECL))->decl_flags.threadprivate_or_deleted_p)
 
 /* Nonzero if DECL was declared with '= default'.  */
 #define DECL_DEFAULTED_FN(DECL) \
@@ -3863,6 +3863,12 @@ enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, OP_FLAG, TYPENAME_FLAG };
 #define SF_INCLASS_INLINE    2  /* The function is an inline, defined
                                   in the class body.  */
 
+/* Used with start_decl's initialized parameter.  */
+#define SD_UNINITIALIZED     0
+#define SD_INITIALIZED       1
+#define SD_DEFAULTED         2
+#define SD_DELETED           3
+
 /* Returns nonzero iff TYPE1 and TYPE2 are the same type, or if TYPE2
    is derived from TYPE1, or if TYPE2 is a pointer (reference) to a
    class derived from the type pointed to (referred to) by TYPE1.  */
index 0d735c4..0f7b5d7 100644 (file)
@@ -3969,14 +3969,14 @@ groktypename (cp_decl_specifier_seq *type_specifiers,
    grokfield.)  The DECL corresponding to the DECLARATOR is returned.
    If an error occurs, the error_mark_node is returned instead.
    
-   DECLSPECS are the decl-specifiers for the declaration.  INITIALIZED is 1
-   if an explicit initializer is present, or 2 for an explicitly defaulted
-   function, or 3 for an explicitly deleted function, but 0 if this is a
-   variable implicitly initialized via a default constructor.  ATTRIBUTES
-   and PREFIX_ATTRIBUTES are GNU attributes associated with this
-   declaration.  *PUSHED_SCOPE_P is set to the scope entered in this
-   function, if any; if set, the caller is responsible for calling
-   pop_scope.  */
+   DECLSPECS are the decl-specifiers for the declaration.  INITIALIZED is
+   SD_INITIALIZED if an explicit initializer is present, or SD_DEFAULTED
+   for an explicitly defaulted function, or SD_DELETED for an explicitly
+   deleted function, but 0 (SD_UNINITIALIZED) if this is a variable
+   implicitly initialized via a default constructor.  ATTRIBUTES and
+   PREFIX_ATTRIBUTES are GNU attributes associated with this declaration.
+   *PUSHED_SCOPE_P is set to the scope entered in this function, if any; if
+   set, the caller is responsible for calling pop_scope.  */
 
 tree
 start_decl (const cp_declarator *declarator,
@@ -4034,7 +4034,7 @@ start_decl (const cp_declarator *declarator,
        return error_mark_node;
 
       case FUNCTION_DECL:
-       if (initialized == 3)
+       if (initialized == SD_DELETED)
          /* We'll handle the rest of the semantics later, but we need to
             set this now so it's visible to duplicate_decls.  */
          DECL_DELETED_FN (decl) = 1;
index 0e56c07..4f19766 100644 (file)
@@ -3767,6 +3767,12 @@ mark_used (tree decl)
   TREE_USED (decl) = 1;
   if (DECL_CLONED_FUNCTION_P (decl))
     TREE_USED (DECL_CLONED_FUNCTION (decl)) = 1;
+  if (TREE_CODE (decl) == FUNCTION_DECL
+      && DECL_DELETED_FN (decl))
+    {
+      error ("deleted function %q+D", decl);
+      error ("used here");
+    }
   /* If we don't need a value, then we don't need to synthesize DECL.  */
   if (skip_evaluation)
     return;
@@ -3830,12 +3836,6 @@ mark_used (tree decl)
       /* If we've already synthesized the method we don't need to
         do the instantiation test below.  */
     }
-  else if (TREE_CODE (decl) == FUNCTION_DECL
-          && DECL_DELETED_FN (decl))
-    {
-      error ("deleted function %q+D", decl);
-      error ("used here");
-    }
   else if ((DECL_NON_THUNK_FUNCTION_P (decl) || TREE_CODE (decl) == VAR_DECL)
           && DECL_LANG_SPECIFIC (decl) && DECL_TEMPLATE_INFO (decl)
           && (!DECL_EXPLICIT_INSTANTIATION (decl)
index 4549f8f..32907b2 100644 (file)
@@ -12610,7 +12610,7 @@ cp_parser_init_declarator (cp_parser* parser,
       || token->type == CPP_OPEN_PAREN
       || token->type == CPP_OPEN_BRACE)
     {
-      is_initialized = 1;
+      is_initialized = SD_INITIALIZED;
       initialization_kind = token->type;
 
       if (token->type == CPP_EQ
@@ -12618,9 +12618,9 @@ cp_parser_init_declarator (cp_parser* parser,
        {
          cp_token *t2 = cp_lexer_peek_nth_token (parser->lexer, 2);
          if (t2->keyword == RID_DEFAULT)
-           is_initialized = 2;
+           is_initialized = SD_DEFAULTED;
          else if (t2->keyword == RID_DELETE)
-           is_initialized = 3;
+           is_initialized = SD_DELETED;
        }
     }
   else
@@ -12633,7 +12633,7 @@ cp_parser_init_declarator (cp_parser* parser,
          cp_parser_error (parser, "expected initializer");
          return error_mark_node;
        }
-      is_initialized = 0;
+      is_initialized = SD_UNINITIALIZED;
       initialization_kind = CPP_EOF;
     }
 
index 24d003f..bf0ff6b 100644 (file)
@@ -704,7 +704,8 @@ check_narrowing (tree type, tree init)
     }
 
   if (!ok)
-    error ("narrowing conversion of %qE to %qT inside { }", init, type);
+    permerror (input_location, "narrowing conversion of %qE to %qT inside { }",
+              init, type);
 }
 
 /* Process the initializer INIT for a variable of type TYPE, emitting
diff --git a/gcc/testsuite/g++.dg/cpp0x/defaulted4.C b/gcc/testsuite/g++.dg/cpp0x/defaulted4.C
new file mode 100644 (file)
index 0000000..5605384
--- /dev/null
@@ -0,0 +1,26 @@
+// PR c++/37208: SFINAE and deleted functions.
+
+// { dg-options "-std=c++0x" }
+// { dg-do compile }
+template<int> struct A { };
+
+template<typename T>
+int& int_if_addable(A<sizeof((*(T*)0) + (*(T*)0))>*);
+
+template<typename T>
+float& int_if_addable(...);
+
+struct X { };
+
+struct Y { };
+Y operator+(Y, Y);
+
+struct Z { };
+Z operator+(Z, Z) = delete;
+
+void f()
+{
+ float& x = int_if_addable<X>(0);
+ int& y = int_if_addable<Y>(0);
+ float& z = int_if_addable<Z>(0);
+}