LCOV - code coverage report
Current view: top level - gcc/c-family - known-headers.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 95.2 % 63 60
Test Date: 2026-02-28 14:20:25 Functions: 100.0 % 15 15
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Support for suggestions about missing #include directives.
       2              :    Copyright (C) 2017-2026 Free Software Foundation, Inc.
       3              : 
       4              : This file is part of GCC.
       5              : 
       6              : GCC is free software; you can redistribute it and/or modify it under
       7              : the terms of the GNU General Public License as published by the Free
       8              : Software Foundation; either version 3, or (at your option) any later
       9              : version.
      10              : 
      11              : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      12              : WARRANTY; without even the implied warranty of MERCHANTABILITY or
      13              : FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      14              : for more details.
      15              : 
      16              : You should have received a copy of the GNU General Public License
      17              : along with GCC; see the file COPYING3.  If not see
      18              : <http://www.gnu.org/licenses/>.  */
      19              : 
      20              : #include "config.h"
      21              : #include "system.h"
      22              : #include "coretypes.h"
      23              : #include "c-family/c-common.h"
      24              : #include "c-family/name-hint.h"
      25              : #include "c-family/known-headers.h"
      26              : #include "gcc-rich-location.h"
      27              : #include "opts.h"
      28              : 
      29              : /* An enum for distinguishing between the C and C++ stdlibs.  */
      30              : 
      31              : enum stdlib
      32              : {
      33              :   STDLIB_C,
      34              :   STDLIB_CPLUSPLUS,
      35              : 
      36              :   NUM_STDLIBS
      37              : };
      38              : 
      39              : /* A struct for associating names in a standard library with the header
      40              :    that should be included to locate them, for each of the C and C++ stdlibs
      41              :    (or NULL, for names that aren't in a header for a particular stdlib).  */
      42              : 
      43              : struct stdlib_hint
      44              : {
      45              :   const char *name;
      46              :   const char *header[NUM_STDLIBS];
      47              : };
      48              : 
      49              : /* Given non-NULL NAME, return the header name defining it (as literal
      50              :    string) within either the standard library (with '<' and '>'), or
      51              :    NULL.
      52              : 
      53              :    Only handle string macros, so that this can be used for
      54              :    get_stdlib_header_for_name and
      55              :    get_c_stdlib_header_for_string_macro_name.  */
      56              : 
      57              : static const char *
      58         4143 : get_string_macro_hint (const char *name, enum stdlib lib)
      59              : {
      60              :   /* <inttypes.h> and <cinttypes>.  */
      61         4143 :   static const char *c99_cxx11_macros[] =
      62              :     { "PRId8", "PRId16", "PRId32", "PRId64",
      63              :       "PRIi8", "PRIi16", "PRIi32", "PRIi64",
      64              :       "PRIo8", "PRIo16", "PRIo32", "PRIo64",
      65              :       "PRIu8", "PRIu16", "PRIu32", "PRIu64",
      66              :       "PRIx8", "PRIx16", "PRIx32", "PRIx64",
      67              :       "PRIX8", "PRIX16", "PRIX32", "PRIX64",
      68              : 
      69              :       "PRIdPTR", "PRIiPTR", "PRIoPTR", "PRIuPTR", "PRIxPTR", "PRIXPTR",
      70              : 
      71              :       "SCNd8", "SCNd16", "SCNd32", "SCNd64",
      72              :       "SCNi8", "SCNi16", "SCNi32", "SCNi64",
      73              :       "SCNo8", "SCNo16", "SCNo32", "SCNo64",
      74              :       "SCNu8", "SCNu16", "SCNu32", "SCNu64",
      75              :       "SCNx8", "SCNx16", "SCNx32", "SCNx64",
      76              : 
      77              :       "SCNdPTR", "SCNiPTR", "SCNoPTR", "SCNuPTR", "SCNxPTR" };
      78              : 
      79         4143 :   if ((lib == STDLIB_C && flag_isoc99)
      80         2224 :       || (lib == STDLIB_CPLUSPLUS && cxx_dialect >= cxx11 ))
      81              :     {
      82              :       const size_t num_c99_cxx11_macros = ARRAY_SIZE (c99_cxx11_macros);
      83       196009 :       for (size_t i = 0; i < num_c99_cxx11_macros; i++)
      84       192529 :         if (strcmp (name, c99_cxx11_macros[i]) == 0)
      85           80 :           return lib == STDLIB_C ? "<inttypes.h>" : "<cinttypes>";
      86              :     }
      87              : 
      88              :   return NULL;
      89              : }
      90              : 
      91              : /* Given non-NULL NAME, return the header name defining it within either
      92              :    the standard library (with '<' and '>'), or NULL.
      93              :    Only handles a subset of the most common names within the stdlibs.  */
      94              : 
      95              : static const char *
      96         4392 : get_stdlib_header_for_name (const char *name, enum stdlib lib)
      97              : {
      98         4392 :   gcc_assert (name);
      99         4392 :   gcc_assert (lib < NUM_STDLIBS);
     100              : 
     101              :   static const stdlib_hint hints[] = {
     102              :     /* <assert.h> and <cassert>.  */
     103              :     {"assert", {"<assert.h>",  "<cassert>"} },
     104              : 
     105              :     /* <errno.h> and <cerrno>.  */
     106              :     {"errno", {"<errno.h>", "<cerrno>"} },
     107              : 
     108              :     /* <limits.h> and <climits>.  */
     109              :     {"CHAR_BIT", {"<limits.h>", "<climits>"} },
     110              :     {"CHAR_MAX", {"<limits.h>", "<climits>"} },
     111              :     {"CHAR_MIN", {"<limits.h>", "<climits>"} },
     112              :     {"INT_MAX", {"<limits.h>", "<climits>"} },
     113              :     {"INT_MIN", {"<limits.h>", "<climits>"} },
     114              :     {"LLONG_MAX", {"<limits.h>", "<climits>"} },
     115              :     {"LLONG_MIN", {"<limits.h>", "<climits>"} },
     116              :     {"LONG_MAX", {"<limits.h>", "<climits>"} },
     117              :     {"LONG_MIN", {"<limits.h>", "<climits>"} },
     118              :     {"MB_LEN_MAX", {"<limits.h>", "<climits>"} },
     119              :     {"SCHAR_MAX", {"<limits.h>", "<climits>"} },
     120              :     {"SCHAR_MIN", {"<limits.h>", "<climits>"} },
     121              :     {"SHRT_MAX", {"<limits.h>", "<climits>"} },
     122              :     {"SHRT_MIN", {"<limits.h>", "<climits>"} },
     123              :     {"UCHAR_MAX", {"<limits.h>", "<climits>"} },
     124              :     {"UINT_MAX", {"<limits.h>", "<climits>"} },
     125              :     {"ULLONG_MAX", {"<limits.h>", "<climits>"} },
     126              :     {"ULONG_MAX", {"<limits.h>", "<climits>"} },
     127              :     {"USHRT_MAX", {"<limits.h>", "<climits>"} },
     128              : 
     129              :     /* <float.h> and <cfloat>.  */
     130              :     {"DBL_MAX", {"<float.h>", "<cfloat>"} },
     131              :     {"DBL_MIN", {"<float.h>", "<cfloat>"} },
     132              :     {"FLT_MAX", {"<float.h>", "<cfloat>"} },
     133              :     {"FLT_MIN", {"<float.h>", "<cfloat>"} },
     134              :     {"LDBL_MAX", {"<float.h>", "<cfloat>"} },
     135              :     {"LDBL_MIN", {"<float.h>", "<cfloat>"} },
     136              : 
     137              :     /* <stdarg.h> and <cstdarg>.  */
     138              :     {"va_list", {"<stdarg.h>", "<cstdarg>"} },
     139              : 
     140              :     /* <stddef.h> and <cstddef>.  */
     141              :     {"NULL", {"<stddef.h>", "<cstddef>"} },
     142              :     {"nullptr_t", {NULL, "<cstddef>"} },
     143              :     {"offsetof", {"<stddef.h>", "<cstddef>"} },
     144              :     {"ptrdiff_t", {"<stddef.h>", "<cstddef>"} },
     145              :     {"size_t", {"<stddef.h>", "<cstddef>"} },
     146              :     {"wchar_t", {"<stddef.h>", NULL /* a keyword in C++ */} },
     147              : 
     148              :     /* <stdio.h> and <cstdio>.  */
     149              :     {"BUFSIZ", {"<stdio.h>", "<cstdio>"} },
     150              :     {"EOF", {"<stdio.h>", "<cstdio>"} },
     151              :     {"FILE", {"<stdio.h>", "<cstdio>"} },
     152              :     {"FILENAME_MAX", {"<stdio.h>", "<cstdio>"} },
     153              :     {"fopen", {"<stdio.h>", "<cstdio>"} },
     154              :     {"fpos_t", {"<stdio.h>", "<cstdio>"} },
     155              :     {"getchar", {"<stdio.h>", "<cstdio>"} },
     156              :     {"printf", {"<stdio.h>", "<cstdio>"} },
     157              :     {"snprintf", {"<stdio.h>", "<cstdio>"} },
     158              :     {"sprintf", {"<stdio.h>", "<cstdio>"} },
     159              :     {"stderr", {"<stdio.h>", "<cstdio>"} },
     160              :     {"stdin", {"<stdio.h>", "<cstdio>"} },
     161              :     {"stdout", {"<stdio.h>", "<cstdio>"} },
     162              : 
     163              :     /* <stdlib.h> and <cstdlib>.  */
     164              :     {"EXIT_FAILURE", {"<stdlib.h>", "<cstdlib>"} },
     165              :     {"EXIT_SUCCESS", {"<stdlib.h>", "<cstdlib>"} },
     166              :     {"abort", {"<stdlib.h>", "<cstdlib>"} },
     167              :     {"atexit", {"<stdlib.h>", "<cstdlib>"} },
     168              :     {"calloc", {"<stdlib.h>", "<cstdlib>"} },
     169              :     {"exit", {"<stdlib.h>", "<cstdlib>"} },
     170              :     {"free", {"<stdlib.h>", "<cstdlib>"} },
     171              :     {"getenv", {"<stdlib.h>", "<cstdlib>"} },
     172              :     {"malloc", {"<stdlib.h>", "<cstdlib>"} },
     173              :     {"realloc", {"<stdlib.h>", "<cstdlib>"} },
     174              : 
     175              :     /* <string.h> and <cstring>.  */
     176              :     {"memchr", {"<string.h>", "<cstring>"} },
     177              :     {"memcmp", {"<string.h>", "<cstring>"} },
     178              :     {"memcpy", {"<string.h>", "<cstring>"} },
     179              :     {"memmove", {"<string.h>", "<cstring>"} },
     180              :     {"memset", {"<string.h>", "<cstring>"} },
     181              :     {"strcat", {"<string.h>", "<cstring>"} },
     182              :     {"strchr", {"<string.h>", "<cstring>"} },
     183              :     {"strcmp", {"<string.h>", "<cstring>"} },
     184              :     {"strcpy", {"<string.h>", "<cstring>"} },
     185              :     {"strerror", {"<string.h>", "<cstring>"} },
     186              :     {"strlen", {"<string.h>", "<cstring>"} },
     187              :     {"strncat", {"<string.h>", "<cstring>"} },
     188              :     {"strncmp", {"<string.h>", "<cstring>"} },
     189              :     {"strncpy", {"<string.h>", "<cstring>"} },
     190              :     {"strrchr", {"<string.h>", "<cstring>"} },
     191              :     {"strspn", {"<string.h>", "<cstring>"} },
     192              :     {"strstr", {"<string.h>", "<cstring>"} },
     193              : 
     194              :     /* <stdint.h>.  */
     195              :     {"PTRDIFF_MAX", {"<stdint.h>", "<cstdint>"} },
     196              :     {"PTRDIFF_MIN", {"<stdint.h>", "<cstdint>"} },
     197              :     {"SIG_ATOMIC_MAX", {"<stdint.h>", "<cstdint>"} },
     198              :     {"SIG_ATOMIC_MIN", {"<stdint.h>", "<cstdint>"} },
     199              :     {"SIZE_MAX", {"<stdint.h>", "<cstdint>"} },
     200              :     {"WINT_MAX", {"<stdint.h>", "<cstdint>"} },
     201              :     {"WINT_MIN", {"<stdint.h>", "<cstdint>"} },
     202              : 
     203              :     /* <time.h>.  */
     204              :     {"asctime", {"<time.h>", "<ctime>"} },
     205              :     {"clock", {"<time.h>", "<ctime>"} },
     206              :     {"clock_t", {"<time.h>", "<ctime>"} },
     207              :     {"ctime", {"<time.h>", "<ctime>"} },
     208              :     {"difftime", {"<time.h>", "<ctime>"} },
     209              :     {"gmtime", {"<time.h>", "<ctime>"} },
     210              :     {"localtime", {"<time.h>", "<ctime>"} },
     211              :     {"mktime", {"<time.h>", "<ctime>"} },
     212              :     {"strftime", {"<time.h>", "<ctime>"} },
     213              :     {"time", {"<time.h>", "<ctime>"} },
     214              :     {"time_t", {"<time.h>", "<ctime>"} },
     215              :     {"tm", {"<time.h>", "<ctime>"} },
     216              : 
     217              :     /* <wchar.h>.  */
     218              :     {"WCHAR_MAX", {"<wchar.h>", "<cwchar>"} },
     219              :     {"WCHAR_MIN", {"<wchar.h>", "<cwchar>"} }
     220              :   };
     221              :   const size_t num_hints = ARRAY_SIZE (hints);
     222       411482 :   for (size_t i = 0; i < num_hints; i++)
     223       407329 :     if (strcmp (name, hints[i].name) == 0)
     224          239 :       return hints[i].header[lib];
     225              : 
     226         4153 :   static const stdlib_hint c99_cxx11_hints[] = {
     227              :     /* <stdbool.h>.  Defined natively in C++.  */
     228              :     {"bool", {"<stdbool.h>", NULL} },
     229              :     {"true", {"<stdbool.h>", NULL} },
     230              :     {"false", {"<stdbool.h>", NULL} },
     231              : 
     232              :     /* <stdint.h> and <cstdint>.  */
     233              :     {"int8_t", {"<stdint.h>", "<cstdint>"} },
     234              :     {"uint8_t", {"<stdint.h>", "<cstdint>"} },
     235              :     {"int16_t", {"<stdint.h>", "<cstdint>"} },
     236              :     {"uint16_t", {"<stdint.h>", "<cstdint>"} },
     237              :     {"int32_t", {"<stdint.h>", "<cstdint>"} },
     238              :     {"uint32_t", {"<stdint.h>", "<cstdint>"} },
     239              :     {"int64_t", {"<stdint.h>", "<cstdint>"} },
     240              :     {"uint64_t", {"<stdint.h>", "<cstdint>"} },
     241              :     {"intptr_t", {"<stdint.h>", "<cstdint>"} },
     242              :     {"uintptr_t", {"<stdint.h>", "<cstdint>"} },
     243              :     {"INT8_MAX", {"<stdint.h>", "<cstdint>"} },
     244              :     {"INT16_MAX", {"<stdint.h>", "<cstdint>"} },
     245              :     {"INT32_MAX", {"<stdint.h>", "<cstdint>"} },
     246              :     {"INT64_MAX", {"<stdint.h>", "<cstdint>"} },
     247              :     {"UINT8_MAX", {"<stdint.h>", "<cstdint>"} },
     248              :     {"UINT16_MAX", {"<stdint.h>", "<cstdint>"} },
     249              :     {"UINT32_MAX", {"<stdint.h>", "<cstdint>"} },
     250              :     {"UINT64_MAX", {"<stdint.h>", "<cstdint>"} },
     251              :     {"INTPTR_MAX", {"<stdint.h>", "<cstdint>"} },
     252              :     {"UINTPTR_MAX", {"<stdint.h>", "<cstdint>"} }
     253              :   };
     254              : 
     255         4153 :   const size_t num_c99_cxx11_hints = sizeof (c99_cxx11_hints)
     256              :                                              / sizeof (c99_cxx11_hints[0]);
     257         4153 :   if ((lib == STDLIB_C && flag_isoc99)
     258         2227 :       || (lib == STDLIB_CPLUSPLUS && cxx_dialect >= cxx11 ))
     259        84594 :     for (size_t i = 0; i < num_c99_cxx11_hints; i++)
     260        81093 :       if (strcmp (name, c99_cxx11_hints[i].name) == 0)
     261           45 :         return c99_cxx11_hints[i].header[lib];
     262              : 
     263         4108 :   return get_string_macro_hint (name, lib);
     264              : }
     265              : 
     266              : /* Given non-NULL NAME, return the header name defining it within the C
     267              :    standard library (with '<' and '>'), or NULL.  */
     268              : 
     269              : const char *
     270         2057 : get_c_stdlib_header_for_name (const char *name)
     271              : {
     272         2057 :   return get_stdlib_header_for_name (name, STDLIB_C);
     273              : }
     274              : 
     275              : /* Given non-NULL NAME, return the header name defining it within the C++
     276              :    standard library (with '<' and '>'), or NULL.  */
     277              : 
     278              : const char *
     279         2335 : get_cp_stdlib_header_for_name (const char *name)
     280              : {
     281         2335 :   return get_stdlib_header_for_name (name, STDLIB_CPLUSPLUS);
     282              : }
     283              : 
     284              : /* Given non-NULL NAME, return the header name defining a string macro
     285              :    within the C standard library (with '<' and '>'), or NULL.  */
     286              : const char *
     287           16 : get_c_stdlib_header_for_string_macro_name (const char *name)
     288              : {
     289           16 :   return get_string_macro_hint (name, STDLIB_C);
     290              : }
     291              : 
     292              : /* Given non-NULL NAME, return the header name defining a string macro
     293              :    within the C++ standard library (with '<' and '>'), or NULL.  */
     294              : const char *
     295           19 : get_cp_stdlib_header_for_string_macro_name (const char *name)
     296              : {
     297           19 :   return get_string_macro_hint (name, STDLIB_CPLUSPLUS);
     298              : }
     299              : 
     300              : /* Implementation of class suggest_missing_header.  */
     301              : 
     302              : /* suggest_missing_header's ctor.  */
     303              : 
     304          337 : suggest_missing_header::suggest_missing_header (location_t loc,
     305              :                                                 const char *name,
     306          337 :                                                 const char *header_hint)
     307          337 : : deferred_diagnostic (loc), m_name_str (name), m_header_hint (header_hint)
     308              : {
     309          337 :   gcc_assert (name);
     310          337 :   gcc_assert (header_hint);
     311          337 : }
     312              : 
     313              : /* suggest_missing_header's dtor.  */
     314              : 
     315          674 : suggest_missing_header::~suggest_missing_header ()
     316              : {
     317          337 :   if (is_suppressed_p ())
     318            0 :     return;
     319              : 
     320          337 :   gcc_rich_location richloc (get_location ());
     321          337 :   maybe_add_include_fixit (&richloc, m_header_hint, true);
     322          337 :   inform (&richloc,
     323              :           "%qs is defined in header %qs;"
     324              :           " this is probably fixable by adding %<#include %s%>",
     325              :           m_name_str, m_header_hint, m_header_hint);
     326          674 : }
     327              : 
     328              : /* Implementation of class suggest_missing_option.  */
     329              : 
     330              : /* suggest_missing_option's ctor.  */
     331              : 
     332            8 : suggest_missing_option::
     333              : suggest_missing_option (location_t loc,
     334              :                         const char *macro_name,
     335            8 :                         diagnostics::option_id option_id)
     336            8 : : deferred_diagnostic (loc), m_name_str (macro_name), m_option_id (option_id)
     337              : {
     338            8 :   gcc_assert (macro_name);
     339            8 :   gcc_assert (option_id.m_idx > 0);
     340            8 : }
     341              : 
     342              : /* suggest_missing_option's dtor.  */
     343              : 
     344           16 : suggest_missing_option::~suggest_missing_option ()
     345              : {
     346            8 :   if (is_suppressed_p ())
     347            0 :     return;
     348              : 
     349            8 :   const char *option_name = cl_options[m_option_id.m_idx].opt_text;
     350            8 :   inform (get_location (),
     351              :           "%qs is defined when using option %qs;"
     352              :           " this is probably fixable by adding %qs to the command-line options",
     353              :           m_name_str, option_name, option_name);
     354           16 : }
     355              : 
     356              : /* macro_like_function_used's ctor.  */
     357              : 
     358           32 : macro_like_function_used::macro_like_function_used (location_t loc, const char *name)
     359           32 : : deferred_diagnostic (loc), m_name_str (name)
     360              : {
     361           32 :   gcc_assert (name);
     362           32 : }
     363              : 
     364              : /* macro_like_function_used's dtor.  */
     365              : 
     366           64 : macro_like_function_used::~macro_like_function_used ()
     367              : {
     368           32 :   if (is_suppressed_p ())
     369            0 :     return;
     370              : 
     371           32 :   inform (get_location (),
     372              :           "%qs is a function-like macro and might be used incorrectly",
     373              :           m_name_str);
     374           64 : }
        

Generated by: LCOV version 2.4-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.