libgcc_s.so.1 exception handling behaviour depending on glibc version

2005-05-18 Thread Stephan Bergmann
Hi all,
I experience the following problem on Linux x86:
I have one version of GCC, call it C1, compiled on a glibc 2.2 (plain 
2.2, that is) machine.  (It happens to be GCC 3.4.1, but the exact 
version is probably irrelevant.)  This build includes a version of 
libgcc_s.so.1.

Additionally, I have a second version of GCC, call it C2, compiled on a 
glibc 2.3 machine.  (For C2, I tested various versions of GCC, from 
3.3.x to 4.0.x, and again the exact version is probably irrelevant.) 
This build includes another version of libgcc_s.so.1.

Now, I have a C++ program consisting of an executable main, built from 
main.cc:

  void f();
  int main() { f(); }
and linked against a shared library libf.so, built from f.cc:
  void f() { try { throw 1; } catch (int) {} }
If I build both main and libf.so with C1, and execute the program so 
that it uses C1's libgcc_s.so.1, it works.

If I build main with C1, and libf.so with C2, and execute the program so 
that it uses C1's libgcc_s.so.1, it aborts.

If I build main with C1, and libf.so with C2, and execute the program so 
that it uses C2's libgcc_s.so.1, it works.

It appears that C1's libgcc_s.so.1 is not compatible with C2's.  I did 
not dig too deep into the code, but it appears that libgcc_s.so.1's 
_Unwind_Find_FDE (in gcc/unwind-dw2-fde-glibc.c) differs depending on 
whether or not [EMAIL PROTECTED] is available in glibc at the 
time the compiler is built; this leads to _Unwind_Find_FDE (called 
indirectly from _Unwind_RaiseException, from f.cc's throw 1) either 
returning null (and the process aborts) or returning non-null (and the 
program works ok).

In an earlier thread 
(), I learned that 
libgcc_s.so.1 changes incompatibly (though backwards compatibly) along 
the dimension of GCC versions (e.g., from GCC 3.2 to 3.3 to 4.0, etc.). 
 Can anybody confirm that it is known and intended that libgcc_s.so.1 
also changes incompatibly (though backwards compatibly, as it appears) 
along the dimension of glibc versions used to build GCC (e.g., from 
glibc 2.2 to 2.2.4 to 2.3 etc.)---or is what I describe above to be 
considered a bug?

Thanks,
-Stephan


abi_tag questions

2015-11-04 Thread Stephan Bergmann
I have two questions regarding the abi_tag attribute (as documented at 
):



1  "The attribute can also be applied to an inline namespace, but does 
not affect the mangled name of the namespace; in this case it is only 
used for -Wabi-tag warnings and automatic tagging of functions and 
variables."


I would naively assume that the "automatic tagging" part means that with


inline namespace n __attribute__((__abi_tag__("t"))) { void f() {} }


n::f would be tagged, but that appears not to be the case?


2  "The argument can be a list of strings of arbitrary length."

Does that mean the list can be empty?


void f() __attribute__((__abi_tag__()));


fails with "error: wrong number of arguments specified for ‘__abi_tag__’ 
attribute" while



inline namespace n __attribute__((__abi_tag__())) {}


is accepted by recent trunk GCC (as well as older versions).

(I stumbled across the latter on Fedora 23, where libstdc++'s 
 "Fix 
abi_tag in special modes" is not yet fixed, so it contains such an empty 
abi_tag on an inline namespace, and Clang with patch 
 "add gcc abi_tag support" produces an 
error.)


Re: abi_tag questions

2015-11-04 Thread Stephan Bergmann

On 11/04/2015 12:50 PM, Jonathan Wakely wrote:

On 4 November 2015 at 17:18, Jonathan Wakely  wrote:

On 4 November 2015 at 14:37, Stephan Bergmann  wrote:

I have two questions regarding the abi_tag attribute (as documented at
<https://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html>):


1  "The attribute can also be applied to an inline namespace, but does not
affect the mangled name of the namespace; in this case it is only used for
-Wabi-tag warnings and automatic tagging of functions and variables."

I would naively assume that the "automatic tagging" part means that with


inline namespace n __attribute__((__abi_tag__("t"))) { void f() {} }



n::f would be tagged, but that appears not to be the case?


It's not tagged, because the tagged namespace "n" is already part of
the mangled name.


Oops, I meant to add that automatic tagging happens in cases like:

inline namespace n __attribute__((__abi_tag__("t"))) { struct X { }; }

X f();

Here ::f will be tagged, because its return type is a type defined in
a tagged namespace.


Thanks, got it.


Re: abi_tag questions

2015-11-09 Thread Stephan Bergmann

On 11/04/2015 12:48 PM, Jonathan Wakely wrote:

On 4 November 2015 at 14:37, Stephan Bergmann  wrote:

I have two questions regarding the abi_tag attribute (as documented at
<https://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html>):

[...]

2  "The argument can be a list of strings of arbitrary length."

Does that mean the list can be empty?


void f() __attribute__((__abi_tag__()));


fails with "error: wrong number of arguments specified for ‘__abi_tag__’
attribute" while


inline namespace n __attribute__((__abi_tag__())) {}


is accepted by recent trunk GCC (as well as older versions).


That seems like a bug.


Filed <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68257> "Reject empty 
abi_tag attribute on inline namespace" now.


C++ name mangling not tracking extern "C"-ness of function types?

2014-06-26 Thread Stephan Bergmann

Quoting gcc/cp/mangle.c@34394:


/* Non-terminal .  NODE is a FUNCTION_TYPE or
   METHOD_TYPE.  If INCLUDE_RETURN_TYPE is non-zero, the return type
   is mangled before the parameter types.

  ::= F [Y]  E   */

static void
write_function_type (type, include_return_type)
 tree type;
 int include_return_type;
{
  MANGLE_TRACE_TREE ("function-type", type);

  write_char ('F');
  /* We don't track whether or not a type is `extern "C"'.  Note that
 you can have an `extern "C"' function that does not have
 `extern "C"' type, and vice versa:

   extern "C" typedef void function_t();
   function_t f; // f has C++ linkage, but its type is
 // `extern "C"'

   typedef void function_t();
   extern "C" function_t f; // Vice versa.

 See [dcl.link].  */
  write_bare_function_type (type, include_return_type);
  write_char ('E');
}


Is there any rationale for not tracking extern "C"-ness here (beyond: 
"its just simpler that way")?  I do understand that technically it 
doesn't make much of a difference whether a function's type is extern 
"C" or not, but it took me by surprise to find this deliberate deviation 
from the Itanium ABI.


Stephan


Disable -std=c++17 "ISO C++1z does not allow dynamic exception specifications"?

2017-02-21 Thread Stephan Bergmann
There is no flag to suppress that error or demote it to a warning, is 
there?  Could be useful when adapting large code bases to C++17 
incrementally.


Re: Disable -std=c++17 "ISO C++1z does not allow dynamic exception specifications"?

2017-02-21 Thread Stephan Bergmann

On 02/21/2017 03:56 PM, Jonathan Wakely wrote:

On 21 February 2017 at 14:55, Jonathan Wakely wrote:

On 21 February 2017 at 14:51, Jakub Jelinek wrote:

On Tue, Feb 21, 2017 at 03:44:17PM +0100, Stephan Bergmann wrote:

There is no flag to suppress that error or demote it to a warning, is there?
Could be useful when adapting large code bases to C++17 incrementally.


It is a warning in C++11/C++14 now, so compile with -std=c++14 and
incrementally fix all those warnings, then switch over to -std=c++17?


Sure, cleaning up is trivial enough, when you have control over the code.


-std=c++17 also turns on P0012R1 (noexcept part of the typesystem), so not
sure what would the deprecated dynamic exception specification mean
together with that (we shouldn't be adding new mangling for the dynamic
exception specification etc.).


We absolutely shouldn't add new mangling, but it could simply mean
noexcept(false).

An exception specification that says "this can throw X, Y and Z" means
it can throw.

I'm not proposing we do that though, I want dynamic exception
specifications to go away ASAP :-) I'm surprised who are trying C++17


s/who are/people who are/


didn't get the memo 10+ years ago that they were broken and useless.


The typical scenario being code base A #include'ing header files from 
code base B.


New GCC 7 -Wformat-truncation suppressed by (and only by) -Og?

2017-02-23 Thread Stephan Bergmann
At least with a recent GCC 7 trunk build ("gcc (GCC) 7.0.1 20170221 
(experimental)"), I noticed that -Wformat-truncation warnings happen to 
not be emitted if and only if -Og is given:



$ cat test.c
#include 
int main() {
char buf[3];
snprintf(buf, sizeof buf, "%s", "foo");
return 0;
}
$ gcc -Wformat-truncation -Og ~/test.c
$ gcc -Wformat-truncation -O ~/test.c
test.c: In function ‘main’:
test.c:4:34: warning: ‘snprintf’ output truncated before the last format 
character [-Wformat-truncation=]
 snprintf(buf, sizeof buf, "%s", "foo");
  ^
test.c:4:5: note: ‘snprintf’ output 4 bytes into a destination of size 3
 snprintf(buf, sizeof buf, "%s", "foo");
 ^~


Any other optimization level (-O1..3/s/fast) does emit the warning.  The 
documentation makes it clear that the behavior of that warning may be 
coupled to the optimization level, but this difference between -Og and 
everything else still looks somewhat odd.  Could it be by mistake?


Re: New GCC 7 -Wformat-truncation suppressed by (and only by) -Og?

2017-02-23 Thread Stephan Bergmann

On 02/23/2017 02:51 PM, Stephan Bergmann wrote:

At least with a recent GCC 7 trunk build ("gcc (GCC) 7.0.1 20170221
(experimental)"), I noticed that -Wformat-truncation warnings happen to
not be emitted if and only if -Og is given:


$ cat test.c
#include 
int main() {
char buf[3];
snprintf(buf, sizeof buf, "%s", "foo");
return 0;
}
$ gcc -Wformat-truncation -Og ~/test.c
$ gcc -Wformat-truncation -O ~/test.c
test.c: In function ‘main’:
test.c:4:34: warning: ‘snprintf’ output truncated before the last
format character [-Wformat-truncation=]
 snprintf(buf, sizeof buf, "%s", "foo");
  ^
test.c:4:5: note: ‘snprintf’ output 4 bytes into a destination of size 3
 snprintf(buf, sizeof buf, "%s", "foo");
 ^~


Any other optimization level (-O1..3/s/fast) does emit the warning.  The


-O0..3, even


documentation makes it clear that the behavior of that warning may be
coupled to the optimization level, but this difference between -Og and
everything else still looks somewhat odd.  Could it be by mistake?




Re: New GCC 7 -Wformat-truncation suppressed by (and only by) -Og?

2017-02-23 Thread Stephan Bergmann

On 02/23/2017 05:02 PM, Martin Sebor wrote:

On 02/23/2017 06:51 AM, Stephan Bergmann wrote:

At least with a recent GCC 7 trunk build ("gcc (GCC) 7.0.1 20170221
(experimental)"), I noticed that -Wformat-truncation warnings happen to
not be emitted if and only if -Og is given:


That's unfortunately a bug.  The warning runs at different stages
depending on whether or not optimization is enabled and it looks
like the global GCC variable it uses to determine this is not set
for -Og.  Can you please open a bug in Bugzilla?


<https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79691> 
"-Wformat-truncation suppressed by (and only by) -Og"


typeid name of non-throwing function type

2017-12-20 Thread Stephan Bergmann

I see with any recent GCC (when targeting the Itanium C++ ABI),


$ cat test.cc
#include 
#include 
void f() noexcept;
int main() { std::cout << typeid(f).name() << '\n'; }

$ g++ -std=c++17 test.cc
$ ./a.out
FvvE


that the function type's mangling doesn't contain the noexcept specifier 
(in which case it would be "DoFvvE").


Is that a deliberate decision in GCC, or does it just happen by accident 
(as for function pointer types, the Itanium ABI encodes noexcept 
specifiers at the __pointer_type_info, not at the underlying 
__function_type_info)?


I'm asking in the context of Clang patch 
 "No -fsanitize=function warning when 
calling noexcept function through non-noexcept pointer in C++17".  Clang 
happens to produce type_info for the noexcept-annotated function type 
(with "DoFvvE" name) in the above example, and not doing so (and instead 
behaving like GCC does) would be one way to solve the issue I want to 
fix with that patch.


Re: typeid name of non-throwing function type

2017-12-20 Thread Stephan Bergmann

On 12/20/2017 03:48 PM, Stephan Bergmann wrote:

I see with any recent GCC (when targeting the Itanium C++ ABI),


$ cat test.cc
#include 
#include 
void f() noexcept;
int main() { std::cout << typeid(f).name() << '\n'; }

$ g++ -std=c++17 test.cc
$ ./a.out
FvvE


that the function type's mangling doesn't contain the noexcept specifier 
(in which case it would be "DoFvvE").


Is that a deliberate decision in GCC, or does it just happen by accident 
(as for function pointer types, the Itanium ABI encodes noexcept 
specifiers at the __pointer_type_info, not at the underlying 
__function_type_info)?


Thinking a bit more about it, I think that's rather a bug in GCC, right?


~ cat test72.cc
#include 
#include 
void f1();
void f2() noexcept;
int main() { std::cout << (typeid(f1) == typeid(f2)) << '\n'; }

~ g++ -std=c++17 test72.cc
~ ./a.out
1


should print "0" instead of "1" (like the version does that compares

  (typeid(&f1) == typeid(&f2))

instead).


Re: typeid name of non-throwing function type

2017-12-21 Thread Stephan Bergmann

On 12/21/2017 07:52 AM, Stephan Bergmann wrote:

Thinking a bit more about it, I think that's rather a bug in GCC, right?


~ cat test72.cc
#include 
#include 
void f1();
void f2() noexcept;
int main() { std::cout << (typeid(f1) == typeid(f2)) << '\n'; }

~ g++ -std=c++17 test72.cc
~ ./a.out
1


should print "0" instead of "1" (like the version does that compares

   (typeid(&f1) == typeid(&f2))

instead).


filed <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83534> "C++17: 
typeinfo for noexcept function lacks noexcept information"


Re: gdb 8.x - g++ 7.x compatibility

2018-02-05 Thread Stephan Bergmann

On 05.02.2018 06:06, Simon Marchi wrote:

On 2018-02-04 02:17 PM, Martin Sebor wrote:

Printing the suffix is unhelpful because it leads to unnecessary
differences in diagnostics (even in non-template contexts).  For
templates with non-type template parameters there is no difference
between, say A<1>, A<1U>, A<(unsigned) 1>, or even A when
Green is an enumerator that evaluates to 1, so including the suffix
serves no useful purpose.


This is the part I don't understand.  In Roman's example, spelling
foo<10> and foo<10u> resulted in two different instantiations of the
template, with different code.  So that means it can make a difference,
can't it?


Yes, for non-type template parameters whose type contains a placeholder 
type (i.e., "auto IVAL" in the earlier example), which is a new feature 
of C++17.


My understanding is that printing the suffix would be essential in such 
cases.


libstdc++: ODR violation when using std::regex with and without -D_GLIBCXX_DEBUG

2018-05-08 Thread Stephan Bergmann
I was recently bitten by the following issue (Linux, libstdc++ 8.0.1): 
A process loads two dynamic libraries A and B both using std::regex, and 
A is compiled without -D_GLIBCXX_DEBUG while B is compiled with 
-D_GLIBCXX_DEBUG.  B creates an instance of std::regex, which internally 
creates a 
std::shared_ptr>>, 
where _NFA has various members of std::__debug::vector type (but which 
isn't reflected in the mangled name of that _NFA instantiation itself).


Now, when that instance of std::regex is destroyed again in library B, 
the 
std::shared_ptr>>::~shared_ptr 
destructor (and functions it in turn calls) that happens to get picked 
is the (inlined, and exported due to default visibility) instance from 
library A.  And that assumes that that _NFA instantiation has members of 
non-debug std::vector type, which causes a crash.


Should it be considered a bug that such mixture of debug and non-debug 
std::regex usage causes ODR violations?


Linker stumbles over non-grouped .text/.rodata for a C++ function

2011-08-31 Thread Stephan Bergmann
I am trying to track down an error that can at least be observed when building 
recent versions of LibreOffice (e.g., revision 
bf3ff35d8c96315c35cf8dc8495be4b488b55cb6 of 
git://anongit.freedesktop.org/libreoffice/core) on Fedora 15 i386 (i.e., with 
GCC 4.6.0 20110603 (Red Hat 4.6.0-10)).  The problem is that linking together 
objects via

> g++ -shared vbarange.o vbasheetobjects.o


fails with errors like

> `.L109' referenced in section 
> `.rodata._ZN19ScVbaCollectionBaseIN4cppu15WeakImplHelper1IN3ooo3vba11XCollection4ItemERKN3com3sun4star3uno3AnyESD_[ScVbaCollectionBase
>  >::Item(com::sun::star::uno::Any const&, com::sun::star::uno::Any const&)]' 
> of vbasheetobjects.o: defined in discarded section 
> `.text._ZN19ScVbaCollectionBaseIN4cppu15WeakImplHelper1IN3ooo3vba11XCollection4ItemERKN3com3sun4star3uno3AnyESD_[non-virtual
>  thunk to ScVbaCollectionBase 
> >::Item(com::sun::star::uno::Any const&, com::sun::star::uno::Any const&)]' 
> of vbasheetobjects.o

The two C++ files vbarange.cxx and vbasheetobjects.cxx are compiled with 
identical g++ command lines, including switches -fPIC -fno-common -pipe 
-fvisibility=hidden -fvisibility-inlines-hidden -std=c++0x -fexceptions 
-fno-enforce-eh-specs -Os besides more mundane -D, -I, -M, and -W switches.  
Both objects include code for the 
_ZThn20_N19ScVbaCollectionBaseIN4cppu15WeakImplHelper1IN3ooo3vba11XCollection4ItemERKN3com3sun4star3uno3AnyESD_
 function, but there are two things that strike me as odd:

First, the code emitted for the two functions is rather different in the two 
object files, even though both are compiled with identical command line 
switches.  One difference is that In vbasheetobjects.o, the code contains a 
.rodata section (see below) with a number of labels into code that follows, 
whereas the code in vbarange.o does not contain such a .rodata section.  Could 
it be that -Os can cause these differences?  (If necessary, I can easily make 
available the -S output for the relevant code from the two different files.)

Second, the directive for the .rodata section mentioned above is

> .section 
> .rodata._ZN19ScVbaCollectionBaseIN4cppu15WeakImplHelper1IN3ooo3vba11XCollection4ItemERKN3com3sun4star3uno3AnyESD_,"aG",@progbits,_ZN19ScVbaCollectionBaseIN4cppu15WeakImplHelper1IN3ooo3vba11XCollection4ItemERKN3com3sun4star3uno3AnyESD_,comdat

while the directive for the corresponding .text section (split in multiple 
parts) is

> .section 
> .text._ZN19ScVbaCollectionBaseIN4cppu15WeakImplHelper1IN3ooo3vba11XCollection4ItemERKN3com3sun4star3uno3AnyESD_,"axG",@progbits,_ZThn20_N19ScVbaCollectionBaseIN4cppu15WeakImplHelper1IN3ooo3vba11XCollection4ItemERKN3com3sun4star3uno3AnyESD_,comdat

Note the difference in the GroupName part of the .section directives, the text 
section using the symbol denoting a non-virtual thunk to the function in 
question.  My understanding of such ELF section groups is weak, but my theory 
is that the .rodata and .text sections should belong to a single group, so that 
the linker would either keep or remove them together. What apparently happens 
instead is that the linker uses the .text section from vbarange.o, drops the 
corresponding .text section from vbasheetobjects.o, and then stumbles over the 
left-over .rodata section.  (Manually adapting the GroupName of the .rodata 
section directive to match the .text section makes the link succeed.)

The problem has been worked around for now in LIbreOffice by compiling 
vbasheetobjects.o without -Os (see 
http://cgit.freedesktop.org/libreoffice/core/commit/?id=148e0ccb50ce419e18e452eb7ccfe03cb4881634
 -- i.e., that change must be reverted before the problem can be observed in 
the code revision mentioned at the beginning).

Can somebody enlighten me why the generated code differs in the first place, 
and whether my theory of non-matching GroupNames is correct?

Thanks,
-Stephan


Re: Linker stumbles over non-grouped .text/.rodata for a C++ function

2011-08-31 Thread Stephan Bergmann
On Aug 31, 2011, at 10:07 PM, Ian Lance Taylor wrote:
> Stephan Bergmann  writes:
> 
>> I am trying to track down an error that can at least be observed when 
>> building recent versions of LibreOffice (e.g., revision 
>> bf3ff35d8c96315c35cf8dc8495be4b488b55cb6 of 
>> git://anongit.freedesktop.org/libreoffice/core) on Fedora 15 i386 (i.e., 
>> with GCC 4.6.0 20110603 (Red Hat 4.6.0-10)).  The problem is that linking 
>> together objects via
>> 
>>> g++ -shared vbarange.o vbasheetobjects.o
>> 
>> 
>> fails with errors like
>> 
>>> `.L109' referenced in section 
>>> `.rodata._ZN19ScVbaCollectionBaseIN4cppu15WeakImplHelper1IN3ooo3vba11XCollection4ItemERKN3com3sun4star3uno3AnyESD_[ScVbaCollectionBase
>>>  >::Item(com::sun::star::uno::Any const&, com::sun::star::uno::Any 
>>> const&)]' of vbasheetobjects.o: defined in discarded section 
>>> `.text._ZN19ScVbaCollectionBaseIN4cppu15WeakImplHelper1IN3ooo3vba11XCollection4ItemERKN3com3sun4star3uno3AnyESD_[non-virtual
>>>  thunk to ScVbaCollectionBase 
>>> >::Item(com::sun::star::uno::Any const&, com::sun::star::uno::Any const&)]' 
>>> of vbasheetobjects.o
> 
> This sounds like a compiler bug.  You are correct that the .text and
> .rodata sections should be using the same section group.  Please file a
> bug report so it is not forgotten.

Done, <http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50255>.

> That said, this message from the linker is a warning, and you can
> normally ignore it.

Hm, for me it resulted in an ld exit code of 1, but maybe that was due to one 
of the additional command line switches apart from -shared when linking (but 
which did not otherwise affect the problem).

-Stephan


Broken link Extended-asm-with-goto.html#Extended-asm-with-goto in online HTML documentation

2013-06-06 Thread Stephan Bergmann
Not sure if it is already known, but noticed that at least in the online 
HTML documentation for all versions since 4.5 (where it was apparently 
introduced), at 
 in the 
paragraph


  Speaking of labels, jumps from one asm to another are not supported. 
The compiler's optimizers do not know about these jumps, and therefore 
they cannot take account of them when deciding how to optimize. See 
Extended asm with goto.


the link of "Extended asm with goto" is

  

to a non-existing




which gets redirected as

  


to a URL with non-matching spaces vs. hyphens in the fragment, so 
doesn't make the browser jump to the 
 
anchor.


Stephan


C++: Letting compiler know asm block can call function that can throw?

2012-03-29 Thread Stephan Bergmann

Hi all,

In LibreOffice's ever-beloved low-level code to synthesize calls to C++ 
virtual functions, I'm having the following problem (on Linux x86_64). 
The function callVirtualMethod at 
 
effectively does the following:


First, call dummy_can_throw_anything that can potentially throw (see 
below for why that's there).  Second, in an asm block, call some virtual 
function (that can potentially throw).  Third, call x86_64::fill_struct 
that can potentially throw (it doesn't, but nobody bothered to annotate 
it as "throw ()").


Now, at least GCC 4.7.0 with -O0 produces a .gcc_except_table section 
for callVirtualMethod, with two call-site table entries each spanning 
the first (dummy_can_throw_anything) and third (x86_64::fill_struct) 
calls, resp., but none spanning the second (asm block) call.  These 
entries are effectively nop, simply calling back into _Unwind_Resume, 
and compiling at higher optimization levels leaves them out anyway 
(leading to callVirtualMethod having no corresponding .gcc_except_table 
section).


The problem is that if the virtual function called through the asm block 
throws an exception, that then immediately leads to std::terminate.  My 
understanding is that because the ip is at the call instruction in the 
asm block that is between the two call-site table entries, the unwind 
machinery thinks this cannot happen and bails out.  (When compiled -O2, 
the code happens to work fine, as there is no .gcc_except_table section 
for this frame at all, so unwinding simply passes through it without 
calling the personality function.)


Making sure that there are no calls to (compiler-visible) functions that 
can throw within callVirtualMethod would happen to make the code also 
work with -O0.  But that would remain a fragile solution.


Is there a way to let the compiler know that the asm block potentially 
calls functions that can throw?  So that it could emit correct code, 
regardless of whether callVirtualMethod happens to have a corresponding 
.gcc_except_table section or not.


(The call to dummy_can_throw_anything, copied from the corresponding 
older code for 32-bit x86, is there for the following reason:  At least 
with some compiler version and some optimization level, on x86 it was 
discovered that the compiler did not emit the .eh_frame data necessary 
for unwinding to successfully pass through this frame at all.  As the 
corresponding x86 code does not have a call to x86_64::fill_struct, the 
compiler apparently considered callVirtualMethod a leaf function and 
optimized accordingly.  The dummy_can_throw_anything hack happened to 
make it do the right thing again, but again this is a fragile solution, 
anyway, that could be replaced with something robust if there were a way 
to annotate the asm block as "calls functions that can throw.")


Stephan


Re: C++: Letting compiler know asm block can call function that can throw?

2012-03-29 Thread Stephan Bergmann

On 03/29/2012 09:44 AM, Jakub Jelinek wrote:

On Thu, Mar 29, 2012 at 09:05:29AM +0200, Stephan Bergmann wrote:

In LibreOffice's ever-beloved low-level code to synthesize calls to
C++ virtual functions, I'm having the following problem (on Linux
x86_64). The function callVirtualMethod 
at<http://cgit.freedesktop.org/libreoffice/core/tree/bridges/source/cpp_uno/gcc3_linux_x86-64/uno2cpp.cxx?id=571876c1234ae55aab0198c7e2caf9049fcd230e#n61>
effectively does the following:

First, call dummy_can_throw_anything that can potentially throw (see
below for why that's there).  Second, in an asm block, call some
virtual function (that can potentially throw).  Third, call
x86_64::fill_struct that can potentially throw (it doesn't, but
nobody bothered to annotate it as "throw ()").


If the asm isn't in headers, but just in a single short source file
or two, you could try compiling that file with -fnon-call-exceptions.
It is nothing I'd recommend for the whole codebase though.


Turns out I had to move the callVirtualMethod function containing the 
asm into a source file of its own, anyway.  (Otherwise, even if it no 
longer explicitly called functions that can throw, and thus no longer 
had corresponding .gcc_except_table entries, exception throwing still 
lead to std::terminate.  There are other functions in the same source 
file callVirtualMethod was originally in that do have .gcc_except_table 
entries.  Kind of invalidates my previous explanation of why exception 
handling bailed out to std::terminate.  Looks like I haven't groked it 
yet, anyway.)


So an explicit -fnon-call-exceptions on the command line seems to indeed 
help.  Unfortunately, moving that into a


  #pragma GCC optimize ("non-call-exceptions")

at the top of the source file that defines callVirtualMethod (and 
nothing more) does *not* work.  Is that a bug?


Anyway, would it be worthwhile filing an RFE for an asm annotation 
telling the compiler that it contains code that can throw?


Thanks,
Stephan


Re: C++: Letting compiler know asm block can call function that can throw?

2012-03-29 Thread Stephan Bergmann

On 03/29/2012 11:16 AM, Richard Guenther wrote:

On Thu, Mar 29, 2012 at 10:47 AM, Stephan Bergmann  wrote:

So an explicit -fnon-call-exceptions on the command line seems to indeed
help.  Unfortunately, moving that into a

  #pragma GCC optimize ("non-call-exceptions")

at the top of the source file that defines callVirtualMethod (and nothing
more) does *not* work.  Is that a bug?


The optimize pragma has only very limited support for this kind of options,
so yes, it's techincally a bug but don't hold your breath.


OK.  (It's just that the way LibreOffice is build, its a PITA to compile 
a single file with differing options...)



Anyway, would it be worthwhile filing an RFE for an asm annotation telling
the compiler that it contains code that can throw?


I suppose yes.


<http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52770> "RFE: Letting 
compiler know asm block can call function that can throw."


Thanks,
Stephan


Re: C++: Letting compiler know asm block can call function that can throw?

2012-03-29 Thread Stephan Bergmann

On 03/29/2012 04:12 PM, Andrew Haley wrote:

On 03/29/2012 02:59 PM, Michael Matz wrote:

Actually, with -fnon-call-exceptions volatile asms are already supposed to
be throwing.  It's just that this got lost with tree-ssa.  With the patch
and -fnon-call-exceptions a simple "__asm__ volatile (...)" is regarded as
possibly throwing.

Without -fnon-call-exceptions some parser changes would be required.  How
about "asm throw (...)" ?


Is there any point?  I would have thought that -fnon-call-exceptions was
exactly what you need.


But it looks wrong to me to have to mark the complete compilation unit 
for something that should only affect a single asm declaration.  (Also, 
having to specify -fnon-call-exceptions "externally," on the command 
line, is somewhat awkward.)


Stephan


Re: C++98/C++11 ABI compatibility for gcc-4.7

2012-06-18 Thread Stephan Bergmann

On 06/15/2012 10:12 PM, James Y Knight wrote:

Whether or not this particular incompatibility was intended or not, the
point remains. You cannot say that GCC devs are taking the C++11 binary
incompatibility issue seriously while:
a) there exist serious ABI incompatibilities between the modes.
b) there is essentially no notice to users about the problem (and lots of
users already brokenly compiling in C++11 mode!)
c) there are no recommendations or plans for how users and distros are
expected to deal with the issue.


Trying to understand what the status quo (in GCC 4.7) is exactly:  The 
source of libstdc++ contains code conditional on 
__GXX_EXPERIMENTAL_CXX0X__ (to differentiate -std=c++11 from -std=c++98 
behavior), but such conditional code happens to remain confined to 
"inline-only" header code for now.  Therefore, a single version of 
libstdc++.so.6 is enough for both -std=c++11 and -std=c++98 applications 
(without needing to resort to additional tricks in the implementation of 
libstdc++).  Is that right?


Stephan


How does _ZNSs4_Rep20_S_empty_rep_storageE (not) become a unique global symbol?

2013-02-19 Thread Stephan Bergmann
I'm puzzled by the following on Linux, where I don't understand what 
causes it that a given symbol is exported as "u" (when viewed with nm, 
which documents "u" as "a unique global symbol. This is a GNU 
extension...") or not:


* On an older toolchain (SLED 11 with GCC 4.3.4 and binutils 2.21.1), we 
have



$ nm -D /usr/lib64/libstdc++.so.6.0.16 | grep empty_rep_storage
002f7660 u _ZNSbIwSt11char_traitsIwESaIwEE4_Rep20_S_empty_rep_storageE
002f7580 B _ZNSs4_Rep20_S_empty_rep_storageE


where the latter (aka "std::basic_string, 
std::allocator >::_Rep::_S_empty_rep_storage") is not exported as 
"u" while the former (aka "std::basic_stringstd::char_traits, std::allocator 
>::_Rep::_S_empty_rep_storage") is.  Also, in other dynamic libraries 
linked with that toolchain, _ZNSs4_Rep20_S_empty_rep_storageE is 
exported as "V", and:


** If libstdc++.so.6 is loaded after one of those other libraries, all 
libraries consistently bind to that other libraries' symbol, and 
everything works well.


** However, if libstdc++.so.6 is loaded first, it binds to its symbol, 
but all those other libraries loaded later bind to one of those other 
libaries' symbol, and there is an invalid delete on an address "0 bytes 
inside data symbol '_ZNSs4_Rep20_S_empty_rep_storageE'" from 
std::basic_stringbuf, std::allocator 
>::overflow(int) (in /usr/lib64/libstdc++.so.6.0.16), as reported by 
valgrind.


* But on a more recent toolchain (F18 with GCC 4.7.2 and binutils 
2.23.51), we have



$ nm -D /usr/lib64/libstdc++.so.6.0.17 | grep empty_rep_storage
003c831024e0 u _ZNSbIwSt11char_traitsIwESaIwEE4_Rep20_S_empty_rep_storageE
003c831024c0 u _ZNSs4_Rep20_S_empty_rep_storageE


Also, in dynamic libraries linked with that toolchain, 
_ZNSs4_Rep20_S_empty_rep_storageE is also exported as "u" and runtime 
behavior is just fine.


Now, why is _ZNSs4_Rep20_S_empty_rep_storageE exported as "B" resp. "V" 
in the first case, while it is consistently "u" in the second?


Stephan


Re: How does _ZNSs4_Rep20_S_empty_rep_storageE (not) become a unique global symbol?

2013-02-20 Thread Stephan Bergmann

On 02/19/2013 07:22 PM, Florian Weimer wrote:

On 02/19/2013 07:06 PM, Stephan Bergmann wrote:

I'm puzzled by the following on Linux, where I don't understand what
causes it that a given symbol is exported as "u" (when viewed with nm,
which documents "u" as "a unique global symbol. This is a GNU
extension...") or not:


We tracked this down to a bug in ld:

<http://sourceware.org/bugzilla/show_bug.cgi?id=15107>


I'm not sure that bug is relevant to my problem.  (I admittedly cannot 
make much from that bug report itself, but when I look at the referenced 
thread <http://sourceware.org/ml/binutils/2013-01/msg00362.html> "ld: 
linking to GNU_UNIQUE symbol does not set ELFOSABI_GNU" I get the 
impression that this is about an .so erroneously marked as "OS/ABI: UNIX 
- System V" instead of "OS/ABI: UNIX - GNU" even though it references a 
GNU_UNIQUE symbol.  But all the relevant libraries in my Fedora 18 case, 
both /usr/lib64/libstdc++.so.6 and those other libraries using 
_ZNSs4_Rep20_S_empty_rep_storageE, are marked as "OS/ABI: UNIX - GNU" 
anway---maybe "by luck" because of something else.)


Again, my problem is as follows:  I have a C++ file that instantiates 
static class template member



  template
typename basic_string<_CharT, _Traits, _Alloc>::size_type
basic_string<_CharT, _Traits, _Alloc>::_Rep::_S_empty_rep_storage[
(sizeof(_Rep_base) + sizeof(_CharT) + sizeof(size_type) - 1) /
  sizeof(size_type)];


from the GCC libstdc++ with _CharT = char, _Traits = 
std::char_traits, _Alloc = std::allocator.  In both my 
cases, the relevant parts of the preprocessed output are the same, but 
in the SLED 11 case, the GCC .s output of that C++ file contains



.weak   _ZNSs4_Rep20_S_empty_rep_storageE
.section
.bss._ZNSs4_Rep20_S_empty_rep_storageE,"awG",@nobits,_ZNSs4_Rep20_S_empty_rep_storageE,comdat
.align 32
.type   _ZNSs4_Rep20_S_empty_rep_storageE, @object
.size   _ZNSs4_Rep20_S_empty_rep_storageE, 32
_ZNSs4_Rep20_S_empty_rep_storageE:
.zero   32


(i.e., "@object") while in the Fedora 18 case, it contains


.weak   _ZNSs4_Rep20_S_empty_rep_storageE
.section
.bss._ZNSs4_Rep20_S_empty_rep_storageE,"awG",@nobits,_ZNSs4_Rep20_S_empty_rep_storageE,comdat
.align 32
.type   _ZNSs4_Rep20_S_empty_rep_storageE, @gnu_unique_object
.size   _ZNSs4_Rep20_S_empty_rep_storageE, 32
_ZNSs4_Rep20_S_empty_rep_storageE:
.zero   32


(i.e., "@gnu_unique_object").  My take (backed by my experience that the 
former case leads to runtime trouble while the latter does not) is that 
the former case is incorrect.  So there must be something that causes 
the erroneous labeling as "@object" instead of "@gnu_unique_object" in 
the GCC .s output in the former case, and I'd like to understand what 
that something is.


Now, one could assume that the toolchain of the former case is old 
enough to not support that "unique global symbol" GNU extension at all. 
 However, there are two things that speak against that:


For one, the former case has


$ nm -D /usr/lib64/libstdc++.so.6.0.16 | grep empty_rep_storage
002f7660 u _ZNSbIwSt11char_traitsIwESaIwEE4_Rep20_S_empty_rep_storageE
002f7580 B _ZNSs4_Rep20_S_empty_rep_storageE


so there /are/ symbols marked as "u" there.  Just, oddly, 
_ZNSs4_Rep20_S_empty_rep_storageE is not.


For another, when I look at libraries built on another old toolchain 
(RHEL 5), the situation is rather different there, in that libstdc++ 
consistently offers those symbols as "V"



$ nm -D /opt/libreoffice4.0/ure/lib/libstdc++.so.6 | grep empty_rep_storage
002efee0 V _ZNSbIwSt11char_traitsIwESaIwEE4_Rep20_S_empty_rep_storageE
002efe00 V _ZNSs4_Rep20_S_empty_rep_storageE


while those other libraries that use _ZNSs4_Rep20_S_empty_rep_storageE 
reference it as "U"



$ nm -D /opt/libreoffice4.0/program/libsdlo.so | grep empty_rep_storage
 U _ZNSs4_Rep20_S_empty_rep_storageE


Stephan


More aggressive GCC 12 -Wmaybe-uninitialized when using

2021-07-22 Thread Stephan Bergmann via Gcc
Compared to GCC 11 (at least gcc-c++-11.1.1-3.fc34.x86_64), recent GCC 
12 trunk emits two "unhelpful" -Wmaybe-uninitialized for



$ cat test.cc
#include 
using fn = std::function;
fn f(fn x) {
fn a;
a = x;
return x;
}



$ ~/gcc/trunk/inst/bin/g++ -c -Wmaybe-uninitialized -O2 test.cc
In file included from 
~/gcc/trunk/inst/include/c++/12.0.0/bits/stl_function.h:60,
 from ~/gcc/trunk/inst/include/c++/12.0.0/functional:49,
 from test.cc:1:
In function ‘std::_Require >, std::is_move_constructible<_Tp>, 
std::is_move_assignable<_Tp> > std::swap(_Tp&, _Tp&) [with _Tp = void (*)(const std::_Any_data&)]’,
inlined from ‘void std::function<_Res(_ArgTypes 
...)>::swap(std::function<_Res(_ArgTypes ...)>&) [with _Res = void; _ArgTypes = 
{}]’ at ~/gcc/trunk/inst/include/c++/12.0.0/bits/std_function.h:529:11,
inlined from ‘std::function<_Res(_ArgTypes ...)>& std::function<_Res(_ArgTypes 
...)>::operator=(const std::function<_Res(_ArgTypes ...)>&) [with _Res = void; _ArgTypes = 
{}]’ at ~/gcc/trunk/inst/include/c++/12.0.0/bits/std_function.h:442:20,
inlined from ‘fn f(fn)’ at test.cc:5:9:
~/gcc/trunk/inst/include/c++/12.0.0/bits/move.h:204:11: warning: 
‘.std::function::_M_invoker’ may be used uninitialized 
[-Wmaybe-uninitialized]
  204 |   _Tp __tmp = _GLIBCXX_MOVE(__a);
  |   ^
In file included from ~/gcc/trunk/inst/include/c++/12.0.0/functional:59,
 from test.cc:1:
~/gcc/trunk/inst/include/c++/12.0.0/bits/std_function.h: In function ‘fn f(fn)’:
~/gcc/trunk/inst/include/c++/12.0.0/bits/std_function.h:442:9: note: 
‘’ declared here
  442 | function(__x).swap(*this);
  | ^
In file included from 
~/gcc/trunk/inst/include/c++/12.0.0/bits/stl_function.h:60,
 from ~/gcc/trunk/inst/include/c++/12.0.0/functional:49,
 from test.cc:1:
In function ‘std::_Require >, 
std::is_move_constructible<_Tp>, std::is_move_assignable<_Tp> > std::swap(_Tp&, _Tp&) [with 
_Tp = std::_Any_data]’,
inlined from ‘void std::function<_Res(_ArgTypes 
...)>::swap(std::function<_Res(_ArgTypes ...)>&) [with _Res = void; _ArgTypes = 
{}]’ at ~/gcc/trunk/inst/include/c++/12.0.0/bits/std_function.h:527:11,
inlined from ‘std::function<_Res(_ArgTypes ...)>& std::function<_Res(_ArgTypes 
...)>::operator=(const std::function<_Res(_ArgTypes ...)>&) [with _Res = void; _ArgTypes = 
{}]’ at ~/gcc/trunk/inst/include/c++/12.0.0/bits/std_function.h:442:20,
inlined from ‘fn f(fn)’ at test.cc:5:9:
~/gcc/trunk/inst/include/c++/12.0.0/bits/move.h:204:11: warning: 
‘*(std::_Any_data*)((char*)& + offsetof(std::function, 
std::function::))’ may be used uninitialized [-Wmaybe-uninitialized]
  204 |   _Tp __tmp = _GLIBCXX_MOVE(__a);
  |   ^
In file included from ~/gcc/trunk/inst/include/c++/12.0.0/functional:59,
 from test.cc:1:
~/gcc/trunk/inst/include/c++/12.0.0/bits/std_function.h: In function ‘fn f(fn)’:
~/gcc/trunk/inst/include/c++/12.0.0/bits/std_function.h:442:9: note: 
‘’ declared here
  442 | function(__x).swap(*this);
  | ^


This appears to be an issue with more aggressive -Wmaybe-uninitialized 
in GCC 12 vs. 11, rather than an issue with changes to  in 
libstdc++ 12 vs. 11, as effectively the same warnings are emitted when I 
use GCC 12 with libstdc++ 11 with



$ ~/gcc/trunk/inst/bin/g++ -c -Wmaybe-uninitialized -O2 -nostdinc++ -isystem 
/usr/include/c++/11 -isystem /usr/include/c++/11/x86_64-redhat-linux test.cc


The warnings may technically be correct, and I'm not sure whether this 
is something that should be addressed in the GCC code emitting the 
warnings or in the libstdc++  implementation.


(I found this when building LibreOffice with recent GCC 12 trunk.)



Re: More aggressive GCC 12 -Wmaybe-uninitialized when using

2021-07-23 Thread Stephan Bergmann via Gcc

On 22/07/2021 12:03, Jonathan Wakely wrote:

This should fix it:

[...]

Thanks; it indeed fixed the LibreOffice build for me.



GCC/Clang attributes guiding warnings about unused entities

2023-04-26 Thread Stephan Bergmann via Gcc

[cross-posting this to both the GCC and Clang communities]

I have two specific issues on the subject I would like to discuss below. 
 But first a quick overview:


C++ has two attributes dealing with warnings about unused entities:

* In one direction (making the compiler suppress warnings it would 
otherwise emit), [[maybe_unused]] (which can be used on lots of 
different kinds of entities) is meant to suppress warnings about 
otherwise unused entities.


* In the other direction (making the compiler emit more warnings than it 
could otherwise infer), [[nodiscard]] (which can be used on certain 
types, functions, and constructors) is meant to cause warnings about 
discarded results of function calls or constructor invocations.  (For a 
[[nodiscard]] type, it warns about discarded results of calls to 
functions returning that type.  For a [[nodiscard]] function, it warns 
about discarded results of calls to that function.  For a [[nodiscard]] 
constructor, it warns about discarded objects initialized via that 
constructor.)


GCC and (through its GCC compatibility) Clang have three additional 
non-standard attributes:


* __attribute__((unused)) behaves mostly the same as [[maybe_unused]].

The one difference is that __attribute__((unused)) applied to a type 
does not warn about that type being unused, but rather warns about 
unreferenced variables of that type.  And it appears that both GCC and 
Clang implement [[maybe_unused]] with the same semantics as 
__attribute__((unused)), and cause [[maybe_unused]] applied to a type to 
warn about unreferenced variables of that type.  The mailing list thread 
starting at  
"[[maybe_unused]] classes" discussed this, and argues that those special 
semantics of __attribute__((unused)) and [[maybe_unused]] applied to a 
type are not actually useful:  The GCC documentation cites as a use case 
"lock or thread classes, which are usually defined and then not 
referenced, but contain constructors and destructors that have 
nontrivial bookkeeping functions".  But the presence of those 
non-trivial con-/destructors will already prevent the compiler from 
emitting warnings about seemingly unused variables of such types.  So 
applying __attribute__((unused)) to such types looks like it does not 
bring any additional value.  Or what do other people think?


* __attribute__((warn_unused_result)) (which can only be applied to 
functions) behaves the same as [[nodiscard]] applied to functions.


* __attribute__((warn_unused)) (which can be applied to class types) is 
meant to allow warnings about unreferenced variables of the given type, 
where the compiler could otherwise not infer that those variables are 
truely unused (because the type has non-trivial con-/destructors). 
(This attribute does not have a standard counterpart.)


Similarly to how [[nodiscard]] can be applied to individual 
constructors, it looks beneficial to me to allow 
__attribute__((warn_unused)) to be applied to individual constructors, 
too.  One example use case is a RAII class that has one constructor that 
does not acquire a resource (often the default constructor) and another 
constructor that does acquire a resource.  So the class itself cannot be 
marked __attribute__((warn_unused)).  But if the non-acquiring 
constructor could individually be marked __attribute__((warn_unused)), 
the compiler could warn about unreferenced variables that are 
initialized via that constructor.   
"Allow `__attribute__((warn_unused))` on individual constructors" would 
implement that for Clang---but was met with some reservation for now, 
due to the already somewhat confusing landscape of standard and 
GCC/Clang-specific attributes guiding warnings about unused entities as 
outlined in this post.  What do other people think about it?  Would it 
be something that GCC would also want to implement?




Re: GCC/Clang attributes guiding warnings about unused entities

2023-04-28 Thread Stephan Bergmann via Gcc

On 4/28/23 11:55, Florian Weimer wrote:

* Stephan Bergmann via Gcc:


[cross-posting this to both the GCC and Clang communities]


I don't see your post here:

   
<https://discourse.llvm.org/search?expanded=true&q=unused%20after%3A2023-04-20>

I don't think this is expected to work from a Discourse point of view.


Yeah, that experiment apparently failed miserably, unfortunately.


* __attribute__((unused)) behaves mostly the same as [[maybe_unused]].

The one difference is that __attribute__((unused)) applied to a type
does not warn about that type being unused, but rather warns about
unreferenced variables of that type.  And it appears that both GCC and
Clang implement [[maybe_unused]] with the same semantics as
__attribute__((unused)), and cause [[maybe_unused]] applied to a type
to warn about unreferenced variables of that type.  The mailing list
thread starting at
<https://lists.isocpp.org/std-discussion/2023/04/2158.php>
"[[maybe_unused]] classes" discussed this, and argues that those
special semantics of __attribute__((unused)) and [[maybe_unused]]
applied to a type are not actually useful:  The GCC documentation
cites as a use case "lock or thread classes, which are usually defined
and then not referenced, but contain constructors and destructors that
have nontrivial bookkeeping functions".  But the presence of those
non-trivial con-/destructors will already prevent the compiler from
emitting warnings about seemingly unused variables of such types.  So
applying __attribute__((unused)) to such types looks like it does not
bring any additional value.  Or what do other people think?


Not sure if I quite understand this.  If the attribute cannot be used to
mark (indirectly) variables of type (say) std::string as worthy of
warnings if they are unused, I think these special cases are not useful.


Not sure if I in turn understand you here.  __attribute__((unused)) and 
[[maybe_unused]] are not meant to "mark [...] variables [...] as worthy 
of warnings if they are unused" anyway?



* __attribute__((warn_unused)) (which can be applied to class types)
   is meant to allow warnings about unreferenced variables of the given
   type, where the compiler could otherwise not infer that those
   variables are truely unused (because the type has non-trivial
   con-/destructors). (This attribute does not have a standard
  counterpart.)

Similarly to how [[nodiscard]] can be applied to individual
constructors, it looks beneficial to me to allow
__attribute__((warn_unused)) to be applied to individual constructors,
too.  One example use case is a RAII class that has one constructor
that does not acquire a resource (often the default constructor) and
another constructor that does acquire a resource.  So the class itself
cannot be marked __attribute__((warn_unused)).  But if the
non-acquiring constructor could individually be marked
__attribute__((warn_unused)), the compiler could warn about
unreferenced variables that are initialized via that constructor.
<https://reviews.llvm.org/D148505> "Allow
`__attribute__((warn_unused))` on individual constructors" would
implement that for Clang---but was met with some reservation for now,
due to the already somewhat confusing landscape of standard and
GCC/Clang-specific attributes guiding warnings about unused entities
as outlined in this post.  What do other people think about it?  Would
it be something that GCC would also want to implement?


How does this interact with deriving warn_unused for std::vector if T
is warn_unused?  That seems like a useful feature, and appears to
require that this is a type property, not a constructor property.


Applying __attribute__((warn_unused)) to types would still be possible. 
The only change would be that, in addition, also individual constructors 
can be marked __attribute__((warn_unused)) (to be used in cases where 
the whole class type can't be).


So this would be largely orthogonal to deriving warn_unused for 
std::vector from T.  (Do we even have such a feature?)  (One could, 
of course, envision an additional feature where warn_unused for the 
construction of a std::vector variable could be derived from whether 
the T constructors used to initialize all the individual vector elements 
are warn_unused.)



And maybe there is a trend to use constructor functions for these guard
variables and auto?  So

   auto g = make_guard(obj);

instead of:

   guard g(obj);


I'm not sure I understand what you want to bring up with this example. 
If guard(T) were a constructor that could benefit from being marked 
__attribute__((warn_unused)) (which it usually wouldn't be, though), 
then, yes, wrapping that in a make_guard function would generally stop 
the compiler from being able to warn about the unused variable g.  (As 
the knowledge which constructor had been used inside make_guard is 
generally lost at the point where the variable g is initialized