diff --git a/regression/ansi-c/gcc_attributes11/main.c b/regression/ansi-c/gcc_attributes11/main.c new file mode 100644 index 00000000000..b69ac3e0e63 --- /dev/null +++ b/regression/ansi-c/gcc_attributes11/main.c @@ -0,0 +1,18 @@ +#ifdef __GNUC__ +// example extracted from SV-COMP's ldv-linux-3.4-simple/ +// 32_7_cpp_false-unreach-call_single_drivers-net-phy-dp83640 +static int __attribute__((__section__(".init.text"))) +__attribute__((no_instrument_function)) dp83640_init(void) +{ + return 0; +} +int init_module(void) __attribute__((alias("dp83640_init"))); +#endif + +int main() +{ +#ifdef __GNUC__ + dp83640_init(); +#endif + return 0; +} diff --git a/regression/ansi-c/gcc_attributes11/test.desc b/regression/ansi-c/gcc_attributes11/test.desc new file mode 100644 index 00000000000..466da18b2b5 --- /dev/null +++ b/regression/ansi-c/gcc_attributes11/test.desc @@ -0,0 +1,8 @@ +CORE +main.c + +^EXIT=0$ +^SIGNAL=0$ +-- +^warning: ignoring +^CONVERSION ERROR$ diff --git a/regression/ansi-c/gcc_attributes9/main.c b/regression/ansi-c/gcc_attributes9/main.c index f18e17aa773..76c7aeeca27 100644 --- a/regression/ansi-c/gcc_attributes9/main.c +++ b/regression/ansi-c/gcc_attributes9/main.c @@ -11,11 +11,23 @@ const char* __attribute__((section("s"))) __attribute__((weak)) bar(); volatile int __attribute__((__section__(".init.data1"))) txt_heap_base1; volatile int __attribute__((__section__(".init.data3"))) txt_heap_base, __attribute__((__section__(".init.data4"))) txt_heap_size; +int __attribute__((__section__(".init.text"))) __attribute__((__cold__)) +__alloc_bootmem_huge_page(void *h); +int __attribute__((__section__(".init.text"))) __attribute__((__cold__)) +alloc_bootmem_huge_page(void *h); +int alloc_bootmem_huge_page(void *h) + __attribute__((weak, alias("__alloc_bootmem_huge_page"))); +int __alloc_bootmem_huge_page(void *h) +{ + return 1; +} #endif int main() { #ifdef __GNUC__ + int r = alloc_bootmem_huge_page(0); + static int __attribute__((section(".data.unlikely"))) __warned; __warned=1; return __warned; diff --git a/src/ansi-c/c_typecheck_base.cpp b/src/ansi-c/c_typecheck_base.cpp index 1d213aa8f0a..890815fcc86 100644 --- a/src/ansi-c/c_typecheck_base.cpp +++ b/src/ansi-c/c_typecheck_base.cpp @@ -708,7 +708,12 @@ void c_typecheck_baset::typecheck_declaration( // alias function need not have been declared yet, thus // can't lookup - symbol.value=symbol_exprt(full_spec.alias); + // also cater for renaming/placement in sections + const auto &renaming_entry = asm_label_map.find(full_spec.alias); + if(renaming_entry == asm_label_map.end()) + symbol.value = symbol_exprt(full_spec.alias); + else + symbol.value = symbol_exprt(renaming_entry->second); symbol.is_macro=true; } @@ -716,8 +721,18 @@ void c_typecheck_baset::typecheck_declaration( apply_asm_label(full_spec.asm_label, symbol); else { - std::string asm_name; - asm_name=id2string(full_spec.section)+"$$"; + // section name is not empty, do a bit of parsing + std::string asm_name = id2string(full_spec.section); + if(asm_name[0] != '.') + { + warning().source_location = symbol.location; + warning() << "section name `" << asm_name + << "' expected to start with `.'" << eom; + } + std::string::size_type primary_section = asm_name.find('.', 1); + if(primary_section != std::string::npos) + asm_name.resize(primary_section); + asm_name += "$$"; if(!full_spec.asm_label.empty()) asm_name+=id2string(full_spec.asm_label); else diff --git a/src/ansi-c/expr2c.cpp b/src/ansi-c/expr2c.cpp index c97b1a9bdb8..1ab40b2004d 100644 --- a/src/ansi-c/expr2c.cpp +++ b/src/ansi-c/expr2c.cpp @@ -8,6 +8,7 @@ Author: Daniel Kroening, kroening@kroening.com #include "expr2c.h" +#include #include #include #include @@ -89,6 +90,9 @@ static std::string clean_identifier(const irep_idt &id) *it2='_'; } + // rewrite . as used in ELF section names + std::replace(dest.begin(), dest.end(), '.', '_'); + return dest; }