Author Topic: Possible bug in LLVM/clang  (Read 4333 times)

0 Members and 1 Guest are viewing this topic.

Online newbrainTopic starter

  • Super Contributor
  • ***
  • Posts: 1719
  • Country: se
Re: Possible bug in LLVM/clang
« Reply #25 on: February 23, 2022, 12:06:36 pm »
Frankly, it's not a good idea to write things this way.
Frankly, I think instead that code says exactly what is meant.

The construct is legal and used for the precise purpose it was introduced, i.e. to provide an (initialized) object without a name.

Apart from compiler bugs (pending of course LLVM project's acknowledgement), why is that not a good idea?
The CL syntax is clear enough and does reduce clutter, I do not consider it obscure in any way - after all, CLs have been with us for more than 20 years.

...
Anyway, these samples can be easily converted into standard C-89
...
To have CLs at least C99 needs to be considered.
I really do not understand the connection: does that dialect (your invention?) support compound literals?
If so, how are they related to the C ones?
It looks more like a pared down version of C++ (which does not have CLs) but:
Is get_address() a constexpr function in the C++ meaning (so it can be used as an initializer) or a keyword/operator (like &)?
Are the various types defined somewhere or implicitly derived?
Nandemo wa shiranai wa yo, shitteru koto dake.
 

Offline DiTBho

  • Super Contributor
  • ***
  • Posts: 3915
  • Country: gb
Re: Possible bug in LLVM/clang
« Reply #26 on: February 23, 2022, 01:24:22 pm »
That is no reason to avoid writing valid code. IDEs are notoriusly buggy in parsing / recognizing code. You just have to live with that.
Now I can accept that compiler bug is a much more valid reason to avoid some constructs. You can ignore IDE, but you can't ignore compiler.

If your colleagues are confused, well ... and if your IDE and ICE are confused, too, well that's is a serious problem when you have to debug and analyze things.
For example, here both the dynamic coverage (performed by the ICE) and the static coverage (performed by the IDE) don't work correctly.




The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Offline DiTBho

  • Super Contributor
  • ***
  • Posts: 3915
  • Country: gb
Re: Possible bug in LLVM/clang
« Reply #27 on: February 23, 2022, 01:43:37 pm »
I really do not understand the connection: does that dialect (your invention?) support compound literals?

Yes. I haven't touched the Clang/C99 internal structure, only a piece of the grammar before the AST, this in order to force people to write clean code, because I am frankly tired to waste my unpaid time refactoring other people's code inside my team.

get_address()

I hacked Clang, and I introduced something that works similarly to sizeof(), but you can translate it with the common "&" operator. There are a variety of reasons for this, including that the trick is also massively used to force the ICE to look at the map file and to pre-load the variable address, so when you debug something you already have things preloaded and ready to be inspected. It saves a lot of time during a debug session, and it also help during the dynamic coverage.
 
Are the various types defined somewhere or implicitly derived?

"p_" automatically defines a typedef pointer, e.g. "p_uint32_t" is equivalent to "typedef uint32_t* p_uint32_t;".
Nothing special, but it saves time, and you can forget to think about it since it automatically generates these things in an header file for you.

Anyway, here *the point* is that even if I translate your source into pure C99, both the unpatched-IDE and ICE are confused, as well as the most of my colleagues.

That's not good for me.


« Last Edit: February 23, 2022, 01:48:57 pm by DiTBho »
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Offline Siwastaja

  • Super Contributor
  • ***
  • Posts: 8172
  • Country: fi
Re: Possible bug in LLVM/clang
« Reply #28 on: February 23, 2022, 01:48:38 pm »
If your colleagues are confused, well ...

... discuss usage of new language features before using them, so that everyone is familiar with them.

Unless your communication is broken, of course, in which case your project is doomed.

Quote
and if your IDE and ICE are confused, too,

If the IDE and ICE claim to understand that standard, then well what can you do? Work around their bugs? At least issue tickets in their bug trackers.

If they honestly do not support that standard, then well, that's a good reason to adhere to older standards. C89 is fine. It just results in more work and possibly worse code.

But you are just so utterly wrong in saying that it is not "good idea" to write modern, normal, standard-compliant code, because you happen to have an old or broken tool that does not support modern, standard-compliant C code.

C is a slowly moving target anyway, and the new standards have mostly evolved for the better. Generally, using the new C standards is good advice; your advice of doing the exact opposite may work in certain niche, like your not-invented-here "#define _IF_ if" style language, but again not as a generic advice.



"p_" automatically defines a typedef pointer, e.g. "p_uint32_t" is equivalent to "typedef uint32_t* p_uint32_t;".
Nothing special, but it saves time, and you can forget to think about it since it automatically generates these things in an header file for you.

Anyway, here *the point* is that even if I translate your source into pure C99, both the unpatched-IDE and ICE are confused, as well as the most of my colleagues.

A very sure way of getting colleagues confused is reinventing standard language constructs like pointers and replace them with your NIH syntax (* -> p_, etc.). The fact that C is powerful enough to come with typedef and define metaprogramming, does not mean you actually have to do this. What a horrible mess! I'm so glad I don't have to work with your code.

But I guess, if your colleagues are using your custom syntax replacing the most basic * and & operators, then showing them any standard C language construct is pretty mind-blowing.
« Last Edit: February 23, 2022, 01:52:35 pm by Siwastaja »
 

Offline DiTBho

  • Super Contributor
  • ***
  • Posts: 3915
  • Country: gb
Re: Possible bug in LLVM/clang
« Reply #29 on: February 23, 2022, 01:52:34 pm »
A very sure way of getting colleagues confused is reinventing standard language constructs like pointers and replace them with your NIH syntax. What a horrible mess! I'm so glad I don't have to work with your code.

Indeed, it was so "clear" that even people in this topic are confused, and I was the first in this topic telling to "remove" the "const" declaration  :-//


The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Offline DiTBho

  • Super Contributor
  • ***
  • Posts: 3915
  • Country: gb
Re: Possible bug in LLVM/clang
« Reply #30 on: February 23, 2022, 01:58:53 pm »
The fact that C is powerful enough to come with typedef and define metaprogramming, does not mean you actually have to do this. What a horrible mess! I'm so glad I don't have to work with your code.

Your opinion, facts are "my code" is back-compatible due to an automatic generator, and the final code usually passes the MISRA-checkers at the first try, and it's usually also well understood by the ICE.

Do you know what it means? Less effort, more good results.
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Offline Siwastaja

  • Super Contributor
  • ***
  • Posts: 8172
  • Country: fi
Re: Possible bug in LLVM/clang
« Reply #31 on: February 23, 2022, 02:05:58 pm »
So what you have is a highly sophisticated, partially custom tooling which makes the language you write not actual C, but more like another language based on C. One with more error checking, better visibility, and so on. Is it worth it?Maybe it is. Is it more reliable, better, safer? Maybe it saves development time? Maybe it's the best thing since sliced bread?

I don't deny any of that. I only question your recommendations of avoiding normal, modern, standard C language only because it does not work in your workflow. Your commentary is more about bragging about your own special unique snowflake (which, to be fair, might be really good), than giving useful or correct advice to others, who just discuss standard C and standard, up-to-date tools that claim full compatibility with the modern standard.

Not interested in dick length comparison. I just use standard C, and I don't have any of that fancy tooling you have. We work fundamentally differently. To me, MISRA means bureaucracy which compromises code quality. To you, it probably means the opposite. That is fine, we can disagree.

But the fact is, no one here except you has your tooling in use.
« Last Edit: February 23, 2022, 02:08:47 pm by Siwastaja »
 

Online Nominal Animal

  • Super Contributor
  • ***
  • Posts: 6255
  • Country: fi
    • My home page and email address
Re: Possible bug in LLVM/clang
« Reply #32 on: February 23, 2022, 02:32:59 pm »
Why not use the much more common pattern,
Code: [Select]
static Block block[] = {
    { .flag = 0, .counter = 0, },
};
instead?  No other changes needed.
 
The following users thanked this post: newbrain, DiTBho

Online newbrainTopic starter

  • Super Contributor
  • ***
  • Posts: 1719
  • Country: se
Re: Possible bug in LLVM/clang
« Reply #33 on: February 23, 2022, 02:53:11 pm »
If your colleagues are confused, well ...
...then I'd like to know their opinion on  _Complex or _Alignas and, god forbid, _Static_assert or _Generic.

C is not evolving blindingly fast (C++, OTOH did make some giant leaps ten years ago and modern C++ is a completely different beast from the one I learned)
All of the above are features that have been there for ten years, compound literals and designated initializers are old enough to drive, drink and vote almost everywhere (not all at the same time, hopefully ;)).

They make programs more expressive while not betraying the C "philosophy" and being evolutionary rather than revolutionary.
Some, like _Generic, make it possible to express new concepts or old concetps that required non standard constructs.
Others, like _Static_assert, can make your program safer.
Some others, like _Atomic, do both.

Though I'll admit I have some antipathy for VLAs, and never use them - but I mostly program for small MCUs, so I think it's justified.

I won't comment on the IDE. VS Code (rather, the C/C++ extension) has no problems with these constructs, but I remember getting squiggles when it was in its infancy for designated initializers. Visual Studio understands them no problems.

Resorting to a training wheels language instead of honing skills might work, but does not seem a viable long term strategy.

EtA: a little example of what I'm saying. Look at this (heavily abridged*) code from NXP SDK, and the hoops it needs to jump through for not being able to use _ALignas (I think they go for C99 compliance, which is a reasonable goal for a generic SDK):
Code: [Select]
struct _lpspi_master_edma_handle
{
...
    edma_tcd_t lpspiSoftwareTCD[3]; /*!<SoftwareTCD, internal used*/
};

status_t LPSPI_MasterTransferEDMA(LPSPI_Type *base, lpspi_master_edma_handle_t *handle, lpspi_transfer_t *transfer)
{
    ...
    edma_tcd_t *softwareTCD_extraBytes    = (edma_tcd_t *)((uint32_t)(&handle->lpspiSoftwareTCD[1]) & (~0x1FU));
    edma_tcd_t *softwareTCD_pcsContinuous = (edma_tcd_t *)((uint32_t)(&handle->lpspiSoftwareTCD[2]) & (~0x1FU));
   ...
}
Why this opprobrium?
Because Transfer Control Descriptors for the iMX.RT DMA must be 32 byte aligned.
Slightly memory wasteful, non portable, non standard and UB as a cherry on top.

*ST: "My HAL is bloated"
NXP: "Hold my beer"
« Last Edit: February 23, 2022, 03:59:20 pm by newbrain »
Nandemo wa shiranai wa yo, shitteru koto dake.
 
The following users thanked this post: Siwastaja, DiTBho

Online newbrainTopic starter

  • Super Contributor
  • ***
  • Posts: 1719
  • Country: se
Re: Possible bug in LLVM/clang
« Reply #34 on: February 23, 2022, 03:07:33 pm »
Code: [Select]
static Block block[] = {
    { .flag = 0, .counter = 0, },
};
This is nice, thanks for the suggestion, I admit I never used this pattern, and did not think of it!

As good as it is, it's still a slightly obfuscated way to convey the meaning.
Constness is replaced with not being an lvalue, and the array is not used as a collection but as a single element.
It is not possible to use in all cases but it's perfect for many.

In any case, compliant code should work.
Nandemo wa shiranai wa yo, shitteru koto dake.
 

Online Nominal Animal

  • Super Contributor
  • ***
  • Posts: 6255
  • Country: fi
    • My home page and email address
Re: Possible bug in LLVM/clang
« Reply #35 on: February 23, 2022, 03:57:19 pm »
Constness is replaced with not being an lvalue, and the array is not used as a collection but as a single element.
It is not possible to use in all cases but it's perfect for many.
True.  I did not mean my question (Why not use...) as a rhetorical one or as a suggestion; I was genuinely wondering why it wasn't used in this case.  I see it constantly in Linux systems programming, you see.

A variant of this – that works on systems that use ELF binaries, including many microcontroller development environments – is to make sure the size of Block is a multiple of its alignment (as it is for all base types), and then use __attribute__((used, section ("name")) to gather all entries (in a pseudorandom order) into a single array, even if compiled in separate compilation units or dynamically linked at run time.  The first element is the address of the __start_name symbol, and the lowest address beyond its end is the address of the __stop_name symbol (whose type does not matter).  See e.g. here for an example I posted some time ago.
 

Online SiliconWizard

  • Super Contributor
  • ***
  • Posts: 14465
  • Country: fr
Re: Possible bug in LLVM/clang
« Reply #36 on: February 23, 2022, 06:24:36 pm »
Thanks everyone for the comments!

First, a side point:
It's a pretty odd use of literals. I would have never thought of doing that.
I see that many, as SiliconWizard, did not like the style.
No problem with that, it's to a large extent personal - to me it's more readable than having a uselessly declared variable

It's not that I don't like the style per se - I can understand your point, considering it more elegant.
It's just that, compound or not, I personally think that literals should never be modifiable objects. That's a general consideration from a language standpoint, so I think the C std made a mess here. They probably did for the same reason as you use that: because it can be elegant and useful, but IMHO it introduces an inconsistency that can only confuse both people using C and people writing compilers for C. For which we have evidence here. =)

As to the literal being modifiable in the context you used it here - I re-read the std, and am still not fully convinced, but you have convinced me that the opposite was also not a given, so I consider it being clear as mud at this point.

Now whether it should be modifiable or not, in both cases, Clang's behavior is bogus. So this is clearly a bug.
 
The following users thanked this post: DiTBho

Offline DiTBho

  • Super Contributor
  • ***
  • Posts: 3915
  • Country: gb
Re: Possible bug in LLVM/clang
« Reply #37 on: February 23, 2022, 06:52:58 pm »
I don't deny any of that. I only question your recommendations of avoiding normal, modern, standard C language only because it does not work in your workflow.

No, I don't recommend it because it makes tools and people confused and it happens even with the standard C99.
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf