]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - gcc/c/c-decl.c
Implement -Wimplicit-fallthrough.
[thirdparty/gcc.git] / gcc / c / c-decl.c
index c173796b438cc65ffb9f678db77c8bcfa11e7b27..9e32be2e8ed1be7eab8ab3cf5d86524a6b4913e7 100644 (file)
@@ -1328,7 +1328,7 @@ pop_scope (void)
                set_type_context (TREE_TYPE (p), context);
            }
 
-         /* Fall through.  */
+         gcc_fallthrough ();
          /* Parameters go in DECL_ARGUMENTS, not BLOCK_VARS, and have
             already been put there by store_parm_decls.  Unused-
             parameter warnings are handled by function.c.
@@ -3088,18 +3088,18 @@ implicit_decl_warning (location_t loc, tree id, tree olddecl)
   if (warn_implicit_function_declaration)
     {
       bool warned;
-      tree hint = NULL_TREE;
+      const char *hint = NULL;
       if (!olddecl)
-       hint = lookup_name_fuzzy (id, FUZZY_LOOKUP_NAME);
+       hint = lookup_name_fuzzy (id, FUZZY_LOOKUP_FUNCTION_NAME);
 
       if (flag_isoc99)
        if (hint)
          {
            gcc_rich_location richloc (loc);
-           richloc.add_fixit_misspelled_id (loc, hint);
+           richloc.add_fixit_replace (hint);
            warned = pedwarn_at_rich_loc
              (&richloc, OPT_Wimplicit_function_declaration,
-              "implicit declaration of function %qE; did you mean %qE?",
+              "implicit declaration of function %qE; did you mean %qs?",
               id, hint);
          }
        else
@@ -3109,10 +3109,10 @@ implicit_decl_warning (location_t loc, tree id, tree olddecl)
        if (hint)
          {
            gcc_rich_location richloc (loc);
-           richloc.add_fixit_misspelled_id (loc, hint);
+           richloc.add_fixit_replace (hint);
            warned = warning_at_rich_loc
              (&richloc, OPT_Wimplicit_function_declaration,
-              G_("implicit declaration of function %qE;did you mean %qE?"),
+              G_("implicit declaration of function %qE;did you mean %qs?"),
               id, hint);
          }
        else
@@ -3327,7 +3327,7 @@ implicitly_declare (location_t loc, tree functionid)
 
   if (decl)
     {
-      if (decl == error_mark_node)
+      if (TREE_CODE (decl) != FUNCTION_DECL)
        return decl;
 
       /* FIXME: Objective-C has weird not-really-builtin functions
@@ -3433,14 +3433,14 @@ undeclared_variable (location_t loc, tree id)
 
   if (current_function_decl == 0)
     {
-      tree guessed_id = lookup_name_fuzzy (id, FUZZY_LOOKUP_NAME);
+      const char *guessed_id = lookup_name_fuzzy (id, FUZZY_LOOKUP_NAME);
       if (guessed_id)
        {
          gcc_rich_location richloc (loc);
-         richloc.add_fixit_misspelled_id (loc, guessed_id);
+         richloc.add_fixit_replace (guessed_id);
          error_at_rich_loc (&richloc,
                             "%qE undeclared here (not in a function);"
-                            " did you mean %qE?",
+                            " did you mean %qs?",
                             id, guessed_id);
        }
       else
@@ -3451,15 +3451,15 @@ undeclared_variable (location_t loc, tree id)
     {
       if (!objc_diagnose_private_ivar (id))
        {
-         tree guessed_id = lookup_name_fuzzy (id, FUZZY_LOOKUP_NAME);
+         const char *guessed_id = lookup_name_fuzzy (id, FUZZY_LOOKUP_NAME);
          if (guessed_id)
            {
              gcc_rich_location richloc (loc);
-             richloc.add_fixit_misspelled_id (loc, guessed_id);
+             richloc.add_fixit_replace (guessed_id);
              error_at_rich_loc
                (&richloc,
                 "%qE undeclared (first use in this function);"
-                " did you mean %qE?",
+                " did you mean %qs?",
                 id, guessed_id);
            }
          else
@@ -3955,45 +3955,6 @@ lookup_name_in_scope (tree name, struct c_scope *scope)
   return NULL_TREE;
 }
 
-/* Specialization of edit_distance_traits for preprocessor macros.  */
-
-template <>
-struct edit_distance_traits<cpp_hashnode *>
-{
-  static size_t get_length (cpp_hashnode *hashnode)
-  {
-    return hashnode->ident.len;
-  }
-
-  static const char *get_string (cpp_hashnode *hashnode)
-  {
-    return (const char *)hashnode->ident.str;
-  }
-};
-
-/* Specialization of best_match<> for finding the closest preprocessor
-   macro to a given identifier.  */
-
-typedef best_match<tree, cpp_hashnode *> best_macro_match;
-
-/* A callback for cpp_forall_identifiers, for use by lookup_name_fuzzy.
-   Process HASHNODE and update the best_macro_match instance pointed to be
-   USER_DATA.  */
-
-static int
-find_closest_macro_cpp_cb (cpp_reader *, cpp_hashnode *hashnode,
-                          void *user_data)
-{
-  if (hashnode->type != NT_MACRO)
-    return 1;
-
-  best_macro_match *bmm = (best_macro_match *)user_data;
-  bmm->consider (hashnode);
-
-  /* Keep iterating.  */
-  return 1;
-}
-
 /* Look for the closest match for NAME within the currently valid
    scopes.
 
@@ -4010,7 +3971,7 @@ find_closest_macro_cpp_cb (cpp_reader *, cpp_hashnode *hashnode,
    It also looks for start_typename keywords, to detect "singed" vs "signed"
    typos.  */
 
-tree
+const char *
 lookup_name_fuzzy (tree name, enum lookup_name_fuzzy_kind kind)
 {
   gcc_assert (TREE_CODE (name) == IDENTIFIER_NODE);
@@ -4021,16 +3982,37 @@ lookup_name_fuzzy (tree name, enum lookup_name_fuzzy_kind kind)
   for (c_scope *scope = current_scope; scope; scope = scope->outer)
     for (c_binding *binding = scope->bindings; binding; binding = binding->prev)
       {
-       if (!binding->id)
+       if (!binding->id || binding->invisible)
          continue;
        /* Don't use bindings from implicitly declared functions,
           as they were likely misspellings themselves.  */
        if (TREE_CODE (binding->decl) == FUNCTION_DECL)
          if (C_DECL_IMPLICIT (binding->decl))
            continue;
-       if (kind == FUZZY_LOOKUP_TYPENAME)
-         if (TREE_CODE (binding->decl) != TYPE_DECL)
-           continue;
+       switch (kind)
+         {
+         case FUZZY_LOOKUP_TYPENAME:
+           if (TREE_CODE (binding->decl) != TYPE_DECL)
+             continue;
+           break;
+
+         case FUZZY_LOOKUP_FUNCTION_NAME:
+           if (TREE_CODE (binding->decl) != FUNCTION_DECL)
+             {
+               /* Allow function pointers.  */
+               if ((VAR_P (binding->decl)
+                    || TREE_CODE (binding->decl) == PARM_DECL)
+                   && TREE_CODE (TREE_TYPE (binding->decl)) == POINTER_TYPE
+                   && (TREE_CODE (TREE_TYPE (TREE_TYPE (binding->decl)))
+                       == FUNCTION_TYPE))
+                 break;
+               continue;
+             }
+           break;
+
+         default:
+           break;
+         }
        bm.consider (binding->id);
       }
 
@@ -4047,8 +4029,7 @@ lookup_name_fuzzy (tree name, enum lookup_name_fuzzy_kind kind)
      non-NULL result for best_macro_match if it's better than any of
      the identifiers already checked, which avoids needless creation
      of identifiers for macro hashnodes.  */
-  best_macro_match bmm (name, bm.get_best_distance ());
-  cpp_forall_identifiers (parse_in, find_closest_macro_cpp_cb, &bmm);
+  best_macro_match bmm (name, bm.get_best_distance (), parse_in);
   cpp_hashnode *best_macro = bmm.get_best_meaningful_candidate ();
   /* If a macro is the closest so far to NAME, use it, creating an
      identifier tree node for it.  */
@@ -4079,7 +4060,11 @@ lookup_name_fuzzy (tree name, enum lookup_name_fuzzy_kind kind)
        }
     }
 
-  return bm.get_best_meaningful_candidate ();
+  tree best = bm.get_best_meaningful_candidate ();
+  if (best)
+    return IDENTIFIER_POINTER (best);
+  else
+    return NULL;
 }
 
 \f
@@ -5117,7 +5102,7 @@ finish_decl (tree decl, location_t init_loc, tree init,
          vec<tree, va_gc> *v;
 
          /* Build "cleanup(&decl)" for the destructor.  */
-         cleanup = build_unary_op (input_location, ADDR_EXPR, decl, 0);
+         cleanup = build_unary_op (input_location, ADDR_EXPR, decl, false);
          vec_alloc (v, 1);
          v->quick_push (cleanup);
          cleanup = c_build_function_call_vec (DECL_SOURCE_LOCATION (decl),
@@ -6725,6 +6710,8 @@ grokdeclarator (const struct c_declarator *declarator,
            type = build_distinct_type_copy (TYPE_MAIN_VARIANT (type));
            TYPE_DOMAIN (type) = build_range_type (sizetype, size_zero_node,
                                                   NULL_TREE);
+           if (orig_qual_indirect == 0)
+             orig_qual_type = NULL_TREE;
          }
        type = c_build_qualified_type (type, type_quals, orig_qual_type,
                                       orig_qual_indirect);
@@ -7895,7 +7882,8 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes,
          else if (!saw_named_field)
            {
              error_at (DECL_SOURCE_LOCATION (x),
-                       "flexible array member in otherwise empty struct");
+                       "flexible array member in a struct with no named "
+                       "members");
              TREE_TYPE (x) = error_mark_node;
            }
        }
@@ -9277,7 +9265,9 @@ finish_function (void)
 
   /* For GNU C extern inline functions disregard inline limits.  */
   if (DECL_EXTERNAL (fndecl)
-      && DECL_DECLARED_INLINE_P (fndecl))
+      && DECL_DECLARED_INLINE_P (fndecl)
+      && (flag_gnu89_inline
+         || lookup_attribute ("gnu_inline", DECL_ATTRIBUTES (fndecl))))
     DECL_DISREGARD_INLINE_LIMITS (fndecl) = 1;
 
   /* Genericize before inlining.  Delay genericizing nested functions
@@ -9814,6 +9804,14 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs,
                error_at (loc,
                          ("both %<long%> and %<float%> in "
                           "declaration specifiers"));
+             else if (specs->typespec_word == cts_floatn_nx)
+               error_at (loc,
+                         ("both %<long%> and %<_Float%d%s%> in "
+                          "declaration specifiers"),
+                         floatn_nx_types[specs->floatn_nx_idx].n,
+                         (floatn_nx_types[specs->floatn_nx_idx].extended
+                          ? "x"
+                          : ""));
              else if (specs->typespec_word == cts_dfloat32)
                error_at (loc,
                          ("both %<long%> and %<_Decimal32%> in "
@@ -9867,6 +9865,14 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs,
                error_at (loc,
                          ("both %<short%> and %<double%> in "
                           "declaration specifiers"));
+             else if (specs->typespec_word == cts_floatn_nx)
+               error_at (loc,
+                         ("both %<short%> and %<_Float%d%s%> in "
+                          "declaration specifiers"),
+                         floatn_nx_types[specs->floatn_nx_idx].n,
+                         (floatn_nx_types[specs->floatn_nx_idx].extended
+                          ? "x"
+                          : ""));
              else if (specs->typespec_word == cts_dfloat32)
                 error_at (loc,
                          ("both %<short%> and %<_Decimal32%> in "
@@ -9911,6 +9917,14 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs,
                error_at (loc,
                          ("both %<signed%> and %<double%> in "
                           "declaration specifiers"));
+             else if (specs->typespec_word == cts_floatn_nx)
+               error_at (loc,
+                         ("both %<signed%> and %<_Float%d%s%> in "
+                          "declaration specifiers"),
+                         floatn_nx_types[specs->floatn_nx_idx].n,
+                         (floatn_nx_types[specs->floatn_nx_idx].extended
+                          ? "x"
+                          : ""));
              else if (specs->typespec_word == cts_dfloat32)
                error_at (loc,
                          ("both %<signed%> and %<_Decimal32%> in "
@@ -9955,6 +9969,14 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs,
                error_at (loc,
                          ("both %<unsigned%> and %<double%> in "
                           "declaration specifiers"));
+             else if (specs->typespec_word == cts_floatn_nx)
+               error_at (loc,
+                         ("both %<unsigned%> and %<_Float%d%s%> in "
+                          "declaration specifiers"),
+                         floatn_nx_types[specs->floatn_nx_idx].n,
+                         (floatn_nx_types[specs->floatn_nx_idx].extended
+                          ? "x"
+                          : ""));
               else if (specs->typespec_word == cts_dfloat32)
                error_at (loc,
                          ("both %<unsigned%> and %<_Decimal32%> in "
@@ -10059,6 +10081,14 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs,
                error_at (loc,
                          ("both %<_Sat%> and %<double%> in "
                           "declaration specifiers"));
+             else if (specs->typespec_word == cts_floatn_nx)
+               error_at (loc,
+                         ("both %<_Sat%> and %<_Float%d%s%> in "
+                          "declaration specifiers"),
+                         floatn_nx_types[specs->floatn_nx_idx].n,
+                         (floatn_nx_types[specs->floatn_nx_idx].extended
+                          ? "x"
+                          : ""));
               else if (specs->typespec_word == cts_dfloat32)
                error_at (loc,
                          ("both %<_Sat%> and %<_Decimal32%> in "
@@ -10092,8 +10122,9 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs,
        }
       else
        {
-         /* "void", "_Bool", "char", "int", "float", "double", "_Decimal32",
-            "__intN", "_Decimal64", "_Decimal128", "_Fract", "_Accum" or
+         /* "void", "_Bool", "char", "int", "float", "double",
+            "_FloatN", "_FloatNx", "_Decimal32", "__intN",
+            "_Decimal64", "_Decimal128", "_Fract", "_Accum" or
             "__auto_type".  */
          if (specs->typespec_word != cts_none)
            {
@@ -10159,10 +10190,13 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs,
                          ("both %<__int%d%> and %<short%> in "
                           "declaration specifiers"),
                          int_n_data[specs->int_n_idx].bitsize);
-             else if (! int_n_enabled_p [specs->int_n_idx])
-               error_at (loc,
-                         "%<__int%d%> is not supported on this target",
-                         int_n_data[specs->int_n_idx].bitsize);
+             else if (! int_n_enabled_p[specs->int_n_idx])
+               {
+                 specs->typespec_word = cts_int_n;
+                 error_at (loc,
+                           "%<__int%d%> is not supported on this target",
+                           int_n_data[specs->int_n_idx].bitsize);
+               }
              else
                {
                  specs->typespec_word = cts_int_n;
@@ -10318,6 +10352,72 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs,
                  specs->locations[cdw_typespec] = loc;
                }
              return specs;
+           CASE_RID_FLOATN_NX:
+             specs->floatn_nx_idx = i - RID_FLOATN_NX_FIRST;
+             if (!in_system_header_at (input_location))
+               pedwarn (loc, OPT_Wpedantic,
+                        "ISO C does not support the %<_Float%d%s%> type",
+                        floatn_nx_types[specs->floatn_nx_idx].n,
+                        (floatn_nx_types[specs->floatn_nx_idx].extended
+                         ? "x"
+                         : ""));
+
+             if (specs->long_p)
+               error_at (loc,
+                         ("both %<long%> and %<_Float%d%s%> in "
+                          "declaration specifiers"),
+                         floatn_nx_types[specs->floatn_nx_idx].n,
+                         (floatn_nx_types[specs->floatn_nx_idx].extended
+                          ? "x"
+                          : ""));
+             else if (specs->short_p)
+               error_at (loc,
+                         ("both %<short%> and %<_Float%d%s%> in "
+                          "declaration specifiers"),
+                         floatn_nx_types[specs->floatn_nx_idx].n,
+                         (floatn_nx_types[specs->floatn_nx_idx].extended
+                          ? "x"
+                          : ""));
+             else if (specs->signed_p)
+               error_at (loc,
+                         ("both %<signed%> and %<_Float%d%s%> in "
+                          "declaration specifiers"),
+                         floatn_nx_types[specs->floatn_nx_idx].n,
+                         (floatn_nx_types[specs->floatn_nx_idx].extended
+                          ? "x"
+                          : ""));
+             else if (specs->unsigned_p)
+               error_at (loc,
+                         ("both %<unsigned%> and %<_Float%d%s%> in "
+                          "declaration specifiers"),
+                         floatn_nx_types[specs->floatn_nx_idx].n,
+                         (floatn_nx_types[specs->floatn_nx_idx].extended
+                          ? "x"
+                          : ""));
+             else if (specs->saturating_p)
+               error_at (loc,
+                         ("both %<_Sat%> and %<_Float%d%s%> in "
+                          "declaration specifiers"),
+                         floatn_nx_types[specs->floatn_nx_idx].n,
+                         (floatn_nx_types[specs->floatn_nx_idx].extended
+                          ? "x"
+                          : ""));
+             else if (FLOATN_NX_TYPE_NODE (specs->floatn_nx_idx) == NULL_TREE)
+               {
+                 specs->typespec_word = cts_floatn_nx;
+                 error_at (loc,
+                           "%<_Float%d%s%> is not supported on this target",
+                           floatn_nx_types[specs->floatn_nx_idx].n,
+                           (floatn_nx_types[specs->floatn_nx_idx].extended
+                            ? "x"
+                            : ""));
+               }
+             else
+               {
+                 specs->typespec_word = cts_floatn_nx;
+                 specs->locations[cdw_typespec] = loc;
+               }
+             return specs;
            case RID_DFLOAT32:
            case RID_DFLOAT64:
            case RID_DFLOAT128:
@@ -10795,6 +10895,16 @@ finish_declspecs (struct c_declspecs *specs)
                         : double_type_node);
        }
       break;
+    case cts_floatn_nx:
+      gcc_assert (!specs->long_p && !specs->short_p
+                 && !specs->signed_p && !specs->unsigned_p);
+      if (FLOATN_NX_TYPE_NODE (specs->floatn_nx_idx) == NULL_TREE)
+       specs->type = integer_type_node;
+      else if (specs->complex_p)
+       specs->type = COMPLEX_FLOATN_NX_TYPE_NODE (specs->floatn_nx_idx);
+      else
+       specs->type = FLOATN_NX_TYPE_NODE (specs->floatn_nx_idx);
+      break;
     case cts_dfloat32:
     case cts_dfloat64:
     case cts_dfloat128: