comp.lang.ada
 help / color / mirror / Atom feed
From: Natasha Kerensikova <lithiumcat@instinctive.eu>
Subject: Strange bug in GNAT
Date: Wed, 2 Jul 2014 18:33:49 +0000 (UTC)
Date: 2014-07-02T18:33:49+00:00	[thread overview]
Message-ID: <slrnlr8k48.i0l.lithiumcat@nat.rebma.instinctive.eu> (raw)

Hello,

I have encoutered a very strange bug in GNAT, and I can't understand how
anything can go wrong to produce such results. And I have not been able
to cut the project into a smallish reproducer. I would love to read your
insight in this.

I would also be interested in whether you can reproduce the problem on
some other platform or compiler version (I'm using GNAT-AUX 4.9.0 on
FreeBSD), but considering it depends on AWS and my personal helper
library, it might be too much to ask.

Fortunately the affected project is open source and published. Please
consider
https://github.com/faelys/simple-webapps/blob/f6b6db20aca49fce4b99c921f80492f47ae8f617/src/simple_webapps-upload_servers.adb#L157-L163

The general context is that the package implements a Dispatcher for AWS,
that starts with a `case` statement on the request, where a special
processing of POST request is performed, GET is processed outside of
the case, and all other methods are responded to with a 405 error.

It used to look like that:

         when others =>
            return AWS.Response.Acknowledge (AWS.Messages.S405);
      end case;

and everything worked fine.

Then I wanted to use templates for HTTP error pages, because my browsers
don't actually show my the HTTP response code, but rather whatever
contents are sent along. The line above sends an empty string, which
isn't terribly useful.

So I wrote a body-local function Error_Page that build the error page
according to the given template, with a hardcoded fallback when no
template file is provided. The quote above was changed to the following:

         when others =>
            return Error_Page
              (AWS.Messages.S405,
               Dispatcher.DB.Query.Data.Error_Template);
      end case;

GNAT refused to compile it, with surprising error messages: it
complained that two unrelated subprograms marked overriding were not
actually overriding (it turned out that they are *all* the overriding
subprograms written after the quote above).

I experimented with changing them from `overriding` to `not overriding`,
and GNAT complained that it's illegal because said subprograms are not
primitive.

How can changing from one of the version above into another can change
de primitiveness of a subprogram!?

Then I removed the overriding indicators entirely, and GNAT still
rejected the file, because a bunch of subprograms were defined without
prior declaration (actually that affected all subprograms after the
change above).

So I also removed the style warnings, and now the package did compile,
but then gnatlink failed with a bunch of missing symbols, corresponding
roughly to the subprograms mentioned in the style errors.

After a lot of experimentation, I found the following workaround, which
is committed:

         when others =>
            begin
               return Error_Page
                 (AWS.Messages.S405,
                  Dispatcher.DB.Query.Data.Error_Template);
            end;
      end case;

How can an anonymous block change anything?

I tried compiling with -gnatD flag, but I couldn't find anything
strange in the diff between with and without the extra begin/end, only a
few more labels and temporary types.

At this point, I'm completely lost on how to proceed. I would love to
report the bug, so that hopefully it might eventually be fixed, but
without a smallish reproducer I don't dare bothering AdaCore.


Now I'm wondering whether something weird might occur with the
expression `Dispatcher.DB.Query.Data`, since in the very same function I
have an uninvestigated GNAT bugbox triggered by

            elsif Dispatcher.DB.Query.Data.Debug_Activated
              and then AWS.Status.URI (Request) = "/dump-form"
            then

but not by

            elsif AWS.Status.URI (Request) = "/dump-form"
              and then Dispatcher.DB.Query.Data.Debug_Activated
            then

For the record, `Dispatcher` is the tagged object on which the function
is primitive, and it's a record with a `DB` component, `Query` is a
primitive function with returns an accessor record, of which `Data` is
the access discriminant, there is an implicit dereference, and
`Debug_Activated` and `Error_Template` are protected functions.


Thanks in advance for your insights,
Natasha


             reply	other threads:[~2014-07-02 18:33 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-07-02 18:33 Natasha Kerensikova [this message]
2014-07-02 20:12 ` Strange bug in GNAT Simon Wright
2014-07-03 13:33   ` G.B.
2014-07-05 15:26     ` Natasha Kerensikova
2014-07-05 15:28   ` Natasha Kerensikova
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox