Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

C front-end: Record extern declarations in current scope #1868

Merged
merged 2 commits into from
Jun 1, 2018

Conversation

tautschnig
Copy link
Collaborator

Previously, extern declarations would only be recorded in the global scope.
While they do belong to the global scope, they still need to take precedence in
name lookups in the local/current scope as well.

Also removing an unnecessary iostream include.

Fixes: #1867

Copy link
Collaborator

@martin-cs martin-cs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like it could fix the issue (given my understanding of the front-end ...). I'm not sure it captures all of the rules described in the C standard. Maybe, depending on what @hannes-steffenhagen-diffblue wanted from / for the original issue he might be able / willing / interested / motivated / inclined to write additional test cases which cover the rules more fully.

@@ -8,8 +8,6 @@ Author: Daniel Kroening, [email protected]

#include "ansi_c_parser.h"

#include <iostream>

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch

@tautschnig
Copy link
Collaborator Author

@hannes-steffenhagen-diffblue Just let us know whether you would be willing/able to provide more tests. Else I'll merge as soon as @kroening approves.

@hannes-steffenhagen-diffblue
Copy link
Contributor

This fixes the issue in the case of a local variable; Unfortunately it doesn't work with parameters, consider

int param;
void function(int param)
{
  printf("%d\n", param);
  {
    extern int param;
    printf("%d\n", param);
  }
}

int main(void)
{
  param = 2;
  function(1);
}

Function parameters have block scope, just like local variables, see 6.2.1.4:

Every other identifier has scope determined by the placement of its declaration (in a
declarator or type specifier). If the declarator or type specifier that declares the identifier
appears outside of any block or list of parameters, the identifier has file scope, which
terminates at the end of the translation unit. If the declarator or type specifier that
declares the identifier appears inside a block or within the list of parameter declarations in
a function definition, the identifier has block scope, which terminates at the end of the
associated block
. If the declarator or type specifier that declares the identifier appears within the list of parameter declarations in a function prototype (not part of a function
definition), the identifier has function prototype scope, which terminates at the end of the
function declarator. If an identifier designates two different entities in the same name
space, the scopes might overlap. If so, the scope of one entity (the inner scope) will be a
strict subset of the scope of the other entity (the outer scope). Within the inner scope, the
identifier designates the entity declared in the inner scope; the entity declared in the outer
scope is hidden (and not visible) within the inner scope.

To do this, function parameter names would have to be rewritten similarly to how local variables currently are (since the have the same scope as top level local variables anyway, they could be rewritten to function_name$$1$$arg_name just like those are. Would that be reasonable @martin-cs ?

@tautschnig
Copy link
Collaborator Author

This fixes the issue in the case of a local variable; Unfortunately it doesn't work with parameters, consider [...]

Are you sure this is actually broken? CBMC verifies the following very much correctly:

#include <stdio.h>
#include <assert.h>

int param;
void function(int param)
{
  printf("%d\n", param);
  {
    extern int param;
    printf("%d\n", param);
    assert(param == 2);
  }
  assert(param == 1);
}

int main(void)
{
  param = 2;
  function(1);
}

To do this, function parameter names would have to be rewritten similarly to how local variables currently are (since the have the same scope as top level local variables anyway, they could be rewritten to function_name$$1$$arg_name just like those are.

Function parameters are rewritten to function_name::arg_name, but indeed at least dump-c is broken for this example.

@tautschnig tautschnig self-assigned this Feb 21, 2018
@hannes-steffenhagen-diffblue
Copy link
Contributor

Ah, you're right, verification does indeed work correctly. I was going off the output of goto-instrument --show-goto-functions, which is incorrect, as is goto-instrument --dump-c. I'm less concerned about that than I am about the verification working, so I'd consider that a different bug to what this is fixing.

@tautschnig
Copy link
Collaborator Author

I have no added the parameter-based test that @hannes-steffenhagen-diffblue proposed and have included a fix that addresses the problems in the output of show-goto-functions or dump-c.

@tautschnig
Copy link
Collaborator Author

I'm not sure what this AppVeyor failure is; I'll wait for Travis to finish to see whether it can give me more clues. (I can't reproduce it locally at the moment.)

@tautschnig
Copy link
Collaborator Author

@karkhaz, everyone: This PR now includes the bugfix 3602d21 - it should possibly be migrated into its own PR, but it's really here where the problems showed up (on regression/cbmc/coverage_report1).

@kroening
Copy link
Member

This one is straight forward, but I am still puzzled by 3602d21.

@tautschnig
Copy link
Collaborator Author

@kroening: what is it that's puzzling? My commit message likely isn't good enough. For a start: the culprit is line 195 of symex_main.cpp, which sets up the eventually broken namespace.

@kroening
Copy link
Member

kroening commented Mar 3, 2018

The next thing that irritates me there is the copy made of the new symbols:
// Clients may need to construct a namespace with both the names in
// the original goto-program and the names generated during symbolic
// execution, so return the names generated through symbolic execution
// through new_symbol_table.
new_symbol_table = state.symbol_table;

@kroening
Copy link
Member

kroening commented Mar 3, 2018

I would say the whole way symbol tables are handled there needs a full re-think.

@tautschnig tautschnig assigned kroening and unassigned tautschnig Apr 27, 2018
Previously, extern declarations would only be recorded in the global scope.
While they do belong to the global scope, they still need to take precedence in
name lookups in the local/current scope as well.

Also removing an unnecessary iostream include.

Fixes: diffblue#1867
…output

While the preceding patch in this series ensures that the internal
representation is consistent, plain-text output would still have collisions
between parameter names and globals declared extern, because parameters were
never renamed. We now detect conflicts between prettified names and global
variable names.

Also added a comment explaining a somewhat obscure bit of code.
@kroening kroening merged commit 57885a5 into diffblue:develop Jun 1, 2018
@tautschnig tautschnig deleted the fix-1867 branch June 1, 2018 09:43
NathanJPhillips pushed a commit to NathanJPhillips/cbmc that referenced this pull request Aug 22, 2018
8de6a33 Merge pull request diffblue#2006 from tautschnig/opt-no-self-loops
6605699 Merge pull request diffblue#2217 from diffblue/c-preprocessing-cleanout
f1d787b Merge pull request diffblue#2166 from tautschnig/out-of-bounds
25339d5 Add option not to transform self-loops into assumes
5e6a3af Merge pull request diffblue#2249 from tautschnig/attribute-used
d3d888b Bounds check for flexible array members
41003e8 Handle negative byte_extract offsets
efea5c4 Fix flattening of access beyond type-specified bounds
0ec87c8 Merge pull request diffblue#2271 from diffblue/letification
090790a Interpret GCC's attribute __used__
7985716 Merge pull request diffblue#2252 from tautschnig/fresh-symbol-cleanup
022846a letify: use irep_hash_mapt when hashing is expensive
15dff7d Merge pull request diffblue#2260 from antlechner/antonia/annotation-class-value
9a0ffae added irep_hash_mapt
da0adfe bugfix: irep_hash_containert now keeps a copy of the contained ireps
45436ce use std::size_t for container sizes
0c26a53 let_count_idt is now a struct
e0a5142 Merge pull request diffblue#2206 from diffblue/use-get_identifier
e0ad069 Add support for Java annotations with Class value
3817341 Merge pull request diffblue#2237 from smowton/smowton/feature/initialize-class-literals
25c097e use get_identifier() instead of get(ID_identifier) on symbols
4eda8ad Java class literals: init using a library hook when possible
70f13f3 Merge pull request diffblue#1906 from tautschnig/missing-return-semantics
57885a5 Merge pull request diffblue#1868 from tautschnig/fix-1867
b49822e Merge pull request diffblue#2028 from tautschnig/regression-fix
2815e84 Merge pull request diffblue#2259 from smowton/smowton/feature/note-abstract-methods
09b8cf7 Merge pull request diffblue#2014 from tautschnig/cadical-experiment
f50237b Merge pull request diffblue#1967 from romainbrenguier/refactor/drop-constraint-inheritance2
3f951dd Merge pull request diffblue#2234 from nmanthey/upstream-fpr
c6c2928 Drop inheritance from constraint on exprt
0ffd0ae Replace negation of constraint by a method
f653dec use compiler defaults for gcc defines
a31f530 remove need to do preprocessing on 16-bit test
24210e9 enable AWS Codebuild to do -m32
bfae4e3 enable Travis to do -m32
34a3d85 Merge pull request diffblue#2247 from antlechner/antonia/annotation-conversion
15ed961 Note when symbol-table entries are abstract methods
3a7135a Add module_dependencies.txt in test folder
1fa0b97 Generalize and rename does_annotation_exist
1db0af4 Define inverse function of convert_annotations
ff25b2c get_max: do not parse every symbol name in the symbol table
b603703 Add missing override
70da606 Merge pull request diffblue#2251 from tautschnig/rename-cleanup
49429cf Merge pull request diffblue#2257 from owen-jones-diffblue/owen-jones-diffblue/fix-cmake-macro
4b7a195 Improve naming of annotation variables
57d96e5 Fix CMake macro
f9058e7 Merge pull request diffblue#2246 from diffblue/z3-fpa
6b0f265 Merge pull request diffblue#2248 from thk123/bugfix/doxygen-including-jbmc
72e99a0 Merge pull request diffblue#2201 from diffblue/remove-incomplete-type-constructors
d4abbea smt2 implementation for popcount_exprt
e8fa1c9 bswap_exprt now knows how many bits a byte has
a6652d2 Merge pull request diffblue#2255 from tautschnig/speedup-no-pointer-check
4b0a2d6 goto_check: do not unnecessarily build size-of expressions
1fe7cd7 remove mathematical_typet() constructor, which produces an incomplete object
25d393b remove vector_typet() constructor, which produces an incomplete object
e7c52e4 remove range_typet() constructor, which produces an incomplete object
f92083d remove array_typet() constructor, which produces an incomplete object
72f63f3 remove tag_typet() constructor, which produces an incomplete object
516ed14 remove symbol_typet() constructor, which produces an incomplete object
4215f21 Consistently use get_fresh_aux_symbol instead of local implementations
e6cd488 Remove unused goto_symext::new_name
c24b820 Remove goto_convertt::lookup
a816b26 Do not include rename.h when not using its functions
52ab088 called_functions: use unordered_set
157a12c Fix doxyfile to include JBMC documentation
026e93f function-pointer-removal: drop unused set
b75fcbc smt2 implementation for bswap_exprt
e276b27 Avoid extern/parameter name collisions in show-goto-functions/dump-c output
87c5948 C front-end: Record extern declarations in current scope
a47941d perf-test: add -W/--witness-check to validate SV-COMP witness checking
5b0395f perf-test: Update Ubuntu AMI ids for latest version
1288ec7 perf-test: speed up builds just like e7bb127 did
afccaec Provide goto-cc in performance tests
f802d87 Support CaDiCaL in performance tests, remove redundant script
7872f7c Replace a missing return value by nondet
829068f Don't require the simplifier to solve this regression test

git-subtree-dir: cbmc
git-subtree-split: 8de6a33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants