aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/name-lookup.c
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@acm.org>2021-02-19 13:10:27 -0800
committerNathan Sidwell <nathan@acm.org>2021-02-19 13:29:48 -0800
commit14886cbe300c144a4390245d0515cdf28fc5f68f (patch)
tree378a970b311b4f7526a132c26a4b72f0330a96db /gcc/cp/name-lookup.c
parentdfa2f821c18b7e926b5f5d6e394a0c915937db5e (diff)
downloadgcc-14886cbe300c144a4390245d0515cdf28fc5f68f.zip
gcc-14886cbe300c144a4390245d0515cdf28fc5f68f.tar.gz
gcc-14886cbe300c144a4390245d0515cdf28fc5f68f.tar.bz2
c++: Incorrect module-number ordering [PR 98741]
One of the very strong invariants in modules is that module numbers are allocated such that (other than the current TU), all imports have lesser module numbers, and also that the binding vector is only appended to with increasing module numbers. This broke down when module-directives became a thing and the preprocessing became entirely decoupled from parsing. We'd load header units and their macros (but not symbols of course) during preprocessing. Then we'd load named modules during parsing. This could lead to the situation where a header unit appearing after a named import had a lower module number than the import. Consequently, if they both bound the same identifier, the binding vector would be misorderd and bad things happen. This patch restores a pending import queue I previously had, but in simpler form (hurrah). During preprocessing we queue all module-directives and when we meet one for a header unit we do the minimal loading for all of the queue, so they get appropriate numbering. Then we load the preprocessor state for the header unit. PR c++/98741 gcc/cp/ * module.cc (pending_imports): New. (declare_module): Adjust test condition. (name_pending_imports): New. (preprocess_module): Reimplement using pending_imports. (preprocessed_module): Move name-getting to name_pending_imports. * name-lookup.c (append_imported_binding_slot): Assert module ordering is increasing. gcc/testsuite/ * g++.dg/modules/pr98741_a.H: New. * g++.dg/modules/pr98741_b.H: New. * g++.dg/modules/pr98741_c.C: New. * g++.dg/modules/pr98741_d.C: New.
Diffstat (limited to 'gcc/cp/name-lookup.c')
-rw-r--r--gcc/cp/name-lookup.c5
1 files changed, 5 insertions, 0 deletions
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index 6a4c106..8e3038c 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -367,6 +367,11 @@ append_imported_binding_slot (tree *slot, tree name, unsigned ix)
last->indices[off].base = ix;
last->indices[off].span = 1;
last->slots[off] = NULL_TREE;
+ /* Check monotonicity. */
+ gcc_checking_assert (last[off ? 0 : -1]
+ .indices[off ? off - 1
+ : BINDING_VECTOR_SLOTS_PER_CLUSTER - 1]
+ .base < ix);
return &last->slots[off];
}