[PATCH 1/2] libstdc++: Count pretty-printed tuple elements from 0 not 1

2021-06-13 Thread Paul Smith via Gcc
Show 0-based offsets for std::tuple members, to match with std::get.

libstdc++-v3/ChangeLog:

* python/libstdcxx/v6/printers.py (StdTuplePrinter): don't increment
self.count until after generating the result string.
---
 libstdc++-v3/python/libstdcxx/v6/printers.py | 13 +++--
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py 
b/libstdc++-v3/python/libstdcxx/v6/printers.py
index 550e0ecdd22..14a6d998690 100644
--- a/libstdc++-v3/python/libstdcxx/v6/printers.py
+++ b/libstdc++-v3/python/libstdcxx/v6/printers.py
@@ -560,16 +560,17 @@ class StdTuplePrinter:
 # Process left node and set it as head.
 self.head  = self.head.cast (nodes[0].type)

-self.count = self.count + 1
-
 # Finally, check the implementation.  If it is
 # wrapped in _M_head_impl return that, otherwise return
 # the value "as is".
 fields = impl.type.fields ()
-if len (fields) < 1 or fields[0].name != "_M_head_impl":
-return ('[%d]' % self.count, impl)
-else:
-return ('[%d]' % self.count, impl['_M_head_impl'])
+if len (fields) > 0 and fields[0].name == "_M_head_impl":
+impl = impl['_M_head_impl']
+
+out = '[%d]' % self.count
+self.count = self.count + 1
+
+return (out, impl)

 def __init__ (self, typename, val):
 self.typename = strip_versioned_namespace(typename)
--
2.28.0



[PATCH 2/2] libstdc++: Use template form for pretty-printing tuple elements

2021-06-13 Thread Paul Smith via Gcc
std::tuple elements are retrieved via std::get<> (template) not
[] (array); have the generated output string match this.

libstdc++-v3/ChangeLog:

* python/libstdcxx/v6/printers.py (StdTuplePrinter): Use <> not [].
---
The previous patch seems uncontroversial to me.  I don't know about this one:
I'm not sure if there's any precedent for this type of output although to me
it looks better since tuples cannot be retrieved via array indexing.

 libstdc++-v3/python/libstdcxx/v6/printers.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py 
b/libstdc++-v3/python/libstdcxx/v6/printers.py
index 14a6d998690..0063a3185a6 100644
--- a/libstdc++-v3/python/libstdcxx/v6/printers.py
+++ b/libstdc++-v3/python/libstdcxx/v6/printers.py
@@ -567,7 +567,7 @@ class StdTuplePrinter:
 if len (fields) > 0 and fields[0].name == "_M_head_impl":
 impl = impl['_M_head_impl']

-out = '[%d]' % self.count
+out = '<%d>' % self.count
 self.count = self.count + 1

 return (out, impl)
--
2.28.0



GCC 12.3 ICE: format(printf...) failing in C++ with virtual inheritance

2023-12-08 Thread Paul Smith via Gcc
I've tried this with both older versions as well as GCC 12.3 (latest I
have access to).  This is on GNU/Linux on x86_64.


I have the following code:

  #include 

  class Exception : public std::exception
  {
  public:
  Exception(const char* text, ...)
__attribute__((format(printf, 2, 3)));
  };

  void foo()
  {
  throw Exception("something bad");
  }

this works fine.

However, due to some diamond inheritance I need to switch to virtual
inheritance here:

  #include 

  class Exception : public /**/ virtual /**/ std::exception
  {
  public:
  Exception(const char* text, ...)
  __attribute__((format(printf, 2, 3)));
  };

  void foo()
  {
  throw Exception("something bad");
  }

this does not work AT ALL.

First, the extra virtual infrastructure means that the offsets we use
(note we need to add one to the format parameters anyway due to the
this pointer I assume) are wrong:

  /tmp/virt.cpp:7:45: error: 'format' attribute argument 2 value '2'  
refers to parameter type 'int'
  7 | __attribute__((format(printf, 2, 3)));
| ^

Just adding 1 to this, for 3, 4, doesn't help:

  /tmp/virt.cpp:7:45: error: 'format' attribute argument 2 value '3'  
refers to parameter type 'const void**'
  7 | __attribute__((format(printf, 3, 4)));
| ^

And if I add 2 instead so it's 4,5 instead, I get an ICE:

  /tmp/virt.cpp: In function 'void foo()':
  /tmp/virt.cpp:12:36: error: 'format' attribute argument 2 value '4'   exceeds 
the number of function parameters 2 [-Werror=attributes]
 12 | throw Exception("something bad");
|^
  /tmp/virt.cpp:12:36: internal compiler error: in get_constant, at 
c-family/c-format.cc:323
  0x7fba675a3082 __libc_start_main
  ../csu/libc-start.c:308
  Please submit a full bug report, with preprocessed source (by using 
-freport-bug).
  Please include the complete backtrace with any bug report.
  See  for instructions.

I'm assuming a bug should be filed for this ICE (can anyone repro it in
the current release?), but does anyone know if there's any way to make
it work in GCC 12.3?


GCC 14.2: Configuring with zstd support

2024-09-23 Thread Paul Smith via Gcc
Many of the GNU toolchain projects are adding zstd compression.  This
is good, but the configure support for this is not ideal.

In particular for GCC, there are a number of issues.

The first problem is that the two subdirectories that use zstd
(libbacktrace and gcc) use very different methods to detect and support
it.


In libbacktrace/configure.ac we have only:

  AC_CHECK_LIB([zstd], [ZSTD_compress],
  [AC_DEFINE(HAVE_ZSTD, 1, [Define if -lzstd is available.])])

This means that the only way to allow libbacktrace to locate the zstd
library, is if it's installed into the base system / sysroot, or else
figuring out what extra global CFLAGS/LDFLAGS/LIBS you need to add. 
And for GCC in particular, since it might be building both stage1 and
stage2, you need to work out how to manage that.

I tried for a number of days and just completely failed to find the
correct incantation, if there even is one: all attempts broke something
somewhere.  It seems that these global variables are not used
everywhere they are needed (during configure tests).  I ended up making
a copy of my sysroot, installing zstd into the copy, and building GCC
with that.


In gcc/configure.ac on the other hand we have:

  AC_ARG_WITH(zstd,
  [AS_HELP_STRING([--with-zstd=PATH],
  [specify prefix directory for installed zstd library.
   Equivalent to --with-zstd-include=PATH/include
   plus --with-zstd-lib=PATH/lib])])
  AC_ARG_WITH(zstd-include,
  [AS_HELP_STRING([--with-zstd-include=PATH],
  [specify directory for installed zstd include files])])
  AC_ARG_WITH(zstd-lib,
  [AS_HELP_STRING([--with-zstd-lib=PATH],
  [specify directory for the installed zstd library])])

which, if it worked, seems to give a lot of flexibility.

However, I've not been able to get this to work because it's not clear
to which stage these paths will be applied.  There's also a weird issue
where if you don't provide the PATH (e.g., just use --with-zstd) then
this code in gcc/configure.ac:

  case "x$with_zstd" in
x) ;;
xno)
  ZSTD_INCLUDE=
  ZSTD_LIB=
  ;;
*) ZSTD_INCLUDE=$with_zstd/include
   ZSTD_LIB=$with_zstd/lib
   ;;
  esac

does the wrong thing because $with_zstd is "yes", so it adds
"-Iyes/include" to the compile line etc.  I guess the idea here is that
the GCC configure script would detect zstd and use it if it's present
so you don't need --with-zstd if it's already in the sysroot, but
usually explicitly adding this allows the configure to fail if it's not
found instead of silently continuing.

It definitely breaks to use the sysroot: "--with-zstd=/sysroot/usr"
will cause the configure to fail with obscure errors because the
compile tests add -I/sysroot/usr/include; this doesn't use -isystem
which means that the fix-includes are searched AFTER this, and so the
un-fixed headers are searched first.


Beyond all that, there's the problem that if you build zstd as a static
library with threading support, you can't link it without -pthread on
the link line.  If you don't use -pthread you get linker errors for
pthread_* symbols and configure decides that zstd is not supported.  I
couldn't find any way to successfully pass this through the various
layers during bootstrap etc., so I had to just build zstd without
threading support for use with GCC.


A lot of these issues could be resolved if GCC's configure (both in
libbacktrace and in gcc) used pkg-config to detect zstd.  The
pkg-config files will give you info about the header file location, the
library location, AND the various linker flags like -pthread.

One issue with this is that when building a cross-compiler we'd need to
distinguish between pkg-config run for the host vs. pkg-config run for
the target.  It's not clear how to handle the standard PKG_CONFIG_*
variables in this situation; since it's peculiar to GCC I doubt the
pkg-config folks have an opinion.  Maybe the user would have to define
a _TARGET variation of these variables, and the makefile would have to
swap them so pkg-config finds the correct ones at the correct time.


Re: Using gcc as a sort of scripting language.

2024-12-28 Thread Paul Smith via Gcc
On Sat, 2024-12-28 at 09:00 -0600, Paul Markfort via Gcc wrote:
> I realize that C is not a line oriented language and usually
> completely ignores line termination characters (so yes this is
> probably not a simple thing to do).

You probably really want this capability added to the preprocessor, not
the compiler.

That's much simpler and will meet your needs just as well.

-- 
Paul D. Smith Find some GNU Make tips at:
https://www.gnu.org   http://make.mad-scientist.net
"Please remain calm...I may be mad, but I am a professional." --Mad
Scientist





Re: RFC: A redesign of `-Mmodules` output

2025-02-28 Thread Paul Smith via Gcc
On Fri, 2025-02-28 at 19:26 +0100, Ben Boeckel via Gcc wrote:
> > In POSIX make, including GNU Make, if a command doesn't modify the
> > modification time of the target then that target is not considered
> > updated, and other targets which list it as a prerequisite are not
> > invoked:
> 
> Hmm. My understanding was that if a recipe is run, its outputs are
> assumed to have been updated. I forget where I saw that, but it
> sticks in my mind for some reason. Experimenting with GNU Make indeed
> does exhibit `restat = 1` behavior out-of-the-box. That's good to
> know :). I'll update my priors.

There is one issue related to this: I don't know if Ninja addresses
this or not: maybe this is what people were thinking of?

Because the modification time of the target is not updated, the recipe
for the the target will always be run (but targets that depend on it
will not be run).

E.g., in my previous example I had:

  ~$ touch three; make MKTWO=echo
  echo two
  two

Now if I run it again after touching "three", the command for "two" is
again run as you'd expect, and "one" is not since "two"'s timestamp is
not changed:

  ~$ touch three; make MKTWO=echo
  echo two
  two

BUT!  Now if I do NOT update "three", "two" is STILL updated, and will
continue to be as long as the "two" target's timestamp is not changed:

  ~$ make MKTWO=echo
  echo two
  two

  ~$ make MKTWO=echo
  echo two
  two

If the recipe to create "two" is complex/long-running then this is not
great.

Only when we allow "two" to actually be modified (in my example, by not
overriding the MKTWO variable), will we get back to "normal" behavior:

  ~$ make
  touch two
  touch one

  ~$ make
  make: 'one' is up to date.

This is the best that make can do, because it relies solely on the
filesystem as its database of "build state" and doesn't preserve any
build state of its own.  Since "two"'s timestamp was not modified make
has no way to know that its recipe was actually run previously.

If the recipe to build "two" is expensive, it's probably better to just
bite the bullet and allow "two" to be updated whenever its
prerequisites change.

The only way for make to do better would be for it to keep its own
database of up-to-date notations, alongside or in addition to the
filesystem's modification time.  That would be a major structural
change, of course.


Re: RFC: A redesign of `-Mmodules` output

2025-02-28 Thread Paul Smith via Gcc
On Fri, 2025-02-28 at 18:05 +0100, Ben Boeckel via Gcc wrote:
> Note that one thing that is missing is ninja's `restat = 1` feature.
> This "restats" the output for the associated rule (probably spelled
> `.RESTAT: output` in Make) and skips running dependent rules if the
> output has not updated the mtime of the output(s) before the rule
> (recipe) was executed. This can be used for modules to not have to
> recompile sources that import the output modules it if they didn't
> change

I've seen this statement a few times and I've read the description of
restat in the Ninja docs and also the above, and I guess I'm just too
dumb to understand it.

Can someone explain with an example?

In POSIX make, including GNU Make, if a command doesn't modify the
modification time of the target then that target is not considered
updated, and other targets which list it as a prerequisite are not
invoked:

  $ cat Makefile
  MKTWO = touch
  one: two ; touch $@
  two: three ; $(MKTWO) $@

When we change "three" and then allow the MKTWO recipe to update "two"
then "one" is out-of-date and rebuilt:

  ~$ touch three; make
  touch two
  touch one

  ~$ touch three; make
  touch two
  touch one

When we change "three" then cause the MKTWO recipe to NOT update "two",
then "one" is not out-of-date and not rebuilt:

  ~$ touch three; make -f /tmp/x3.mk MKTWO=echo
  echo two
  two


Can someone explain how the Ninja "restat" feature differs from this?


Re: RFC: A redesign of `-Mmodules` output

2025-02-28 Thread Paul Smith via Gcc
On Fri, 2025-02-28 at 13:07 -0500, Paul Smith via Gcc wrote:
>   ~$ touch three; make -f /tmp/x3.mk MKTWO=echo

Sorry this should be just "make MKTWO=echo"; my typo.