Ada: Fix segfault on uninitialized variable as operand of primitive operator
[gcc-git-mirror.git] / libcc1 / context.cc
blobaf5884b3db99c1cc86d948bbb5f6e7e29c937e4d
1 /* Generic plugin context
2 Copyright (C) 2020-2025 Free Software Foundation, Inc.
4 This file is part of GCC.
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.
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.
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/>. */
20 #include <cc1plugin-config.h>
22 #undef PACKAGE_NAME
23 #undef PACKAGE_STRING
24 #undef PACKAGE_TARNAME
25 #undef PACKAGE_VERSION
27 #include "../gcc/config.h"
29 #undef PACKAGE_NAME
30 #undef PACKAGE_STRING
31 #undef PACKAGE_TARNAME
32 #undef PACKAGE_VERSION
34 #include "gcc-plugin.h"
35 #include "system.h"
36 #include "coretypes.h"
37 #include "stringpool.h"
38 #include "hash-set.h"
39 #include "diagnostic.h"
40 #include "langhooks.h"
41 #include "langhooks-def.h"
42 #include "diagnostic-format-text.h"
44 #include "gcc-interface.h"
46 #include "context.hh"
47 #include "marshall.hh"
51 #ifdef __GNUC__
52 #pragma GCC visibility push(default)
53 #endif
54 int plugin_is_GPL_compatible;
55 #ifdef __GNUC__
56 #pragma GCC visibility pop
57 #endif
59 cc1_plugin::plugin_context *cc1_plugin::current_context;
63 // This is put into the lang hooks when the plugin starts.
65 static void
66 plugin_print_error_function (diagnostic_text_output_format &text_output,
67 const char *file,
68 const diagnostic_info *diagnostic)
70 if (current_function_decl != NULL_TREE
71 && DECL_NAME (current_function_decl) != NULL_TREE
72 && strcmp (IDENTIFIER_POINTER (DECL_NAME (current_function_decl)),
73 GCC_FE_WRAPPER_FUNCTION) == 0)
74 return;
75 lhd_print_error_function (text_output, file, diagnostic);
80 location_t
81 cc1_plugin::plugin_context::get_location_t (const char *filename,
82 unsigned int line_number)
84 if (filename == NULL)
85 return UNKNOWN_LOCATION;
87 filename = intern_filename (filename);
88 linemap_add (line_table, LC_ENTER, false, filename, line_number);
89 location_t loc = linemap_line_start (line_table, line_number, 0);
90 linemap_add (line_table, LC_LEAVE, false, NULL, 0);
91 return loc;
94 // Add a file name to FILE_NAMES and return the canonical copy.
95 const char *
96 cc1_plugin::plugin_context::intern_filename (const char *filename)
98 const char **slot = file_names.find_slot (filename, INSERT);
99 if (*slot == NULL)
101 /* The file name must live as long as the line map, which
102 effectively means as long as this compilation. So, we copy
103 the string here but never free it. */
104 *slot = xstrdup (filename);
106 return *slot;
109 void
110 cc1_plugin::plugin_context::mark ()
112 for (const auto &item : address_map)
114 ggc_mark (item->decl);
115 ggc_mark (item->address);
118 for (const auto &item : preserved)
119 ggc_mark (&item);
124 // Perform GC marking.
126 static void
127 gc_mark (void *, void *)
129 if (cc1_plugin::current_context != NULL)
130 cc1_plugin::current_context->mark ();
133 void
134 cc1_plugin::generic_plugin_init (struct plugin_name_args *plugin_info,
135 unsigned int version)
137 long fd = -1;
138 for (int i = 0; i < plugin_info->argc; ++i)
140 if (strcmp (plugin_info->argv[i].key, "fd") == 0)
142 char *tail;
143 errno = 0;
144 fd = strtol (plugin_info->argv[i].value, &tail, 0);
145 if (*tail != '\0' || errno != 0)
146 fatal_error (input_location,
147 "%s: invalid file descriptor argument to plugin",
148 plugin_info->base_name);
149 break;
152 if (fd == -1)
153 fatal_error (input_location,
154 "%s: required plugin argument %<fd%> is missing",
155 plugin_info->base_name);
157 current_context = new plugin_context (fd);
159 // Handshake.
160 cc1_plugin::protocol_int h_version;
161 if (!current_context->require ('H')
162 || ! ::cc1_plugin::unmarshall (current_context, &h_version))
163 fatal_error (input_location,
164 "%s: handshake failed", plugin_info->base_name);
165 if (h_version != version)
166 fatal_error (input_location,
167 "%s: unknown version in handshake", plugin_info->base_name);
169 register_callback (plugin_info->base_name, PLUGIN_GGC_MARKING,
170 gc_mark, NULL);
172 lang_hooks.print_error_function = plugin_print_error_function;