Using .macro argument in .error message?

Georg-Johann Lay avr@gjlay.de
Fri Jun 12 15:16:54 GMT 2026


Am 12.06.26 um 08:38 schrieb Jan Beulich:
> On 11.06.2026 18:14, Georg-Johann Lay via Binutils wrote:
>> Am 11.06.26 um 17:17 schrieb Jan Beulich:
>>> On 11.06.2026 16:54, Georg-Johann Lay wrote:
>>>> Am 11.06.26 um 16:18 schrieb Jan Beulich:
>>>>> On 11.06.2026 15:42, Georg-Johann Lay wrote:
>>>>>> Am 11.06.26 um 15:22 schrieb Jan Beulich:
>>>>>>> On 10.06.2026 11:54, Georg-Johann Lay wrote:
>>>>>>>> Am 10.06.26 um 11:27 schrieb Jan Beulich:
>>>>>>>>> On 07.06.2026 21:16, Georg-Johann Lay via Binutils wrote:
>>>>>>>>>> Test case err.sx:
>>>>>>>>>>
>>>>>>>>>> .macro Test data
>>>>>>>>>>           .if \data < 0
>>>>>>>>>>               .error "value \data is negative"
>>>>>>>>>>           .endif
>>>>>>>>>> .endm
>>>>>>>>>>
>>>>>>>>>>           Test -1
>>>>>>>>>>
>>>>>>>>>> $ avr-as err.sx -v
>>>>>>>>>> GNU assembler version 2.45.50 (avr) using BFD version (GNU Binutils)
>>>>>>>>>> 2.45.50.20250718
>>>>>>>>>> err.sx: Assembler messages:
>>>>>>>>>> err.sx: Warning: unknown escape '\d' in string; ignored
>>>>>>>>>> err.sx:3: Error: value -1 is negative
>>>>>>>>>> err.sx:7:  Info: macro invoked from here
>>>>>>>>>>
>>>>>>>>>> While the printed error message is as expected, there is a spurious
>>>>>>>>>> warning about using \d in the string.
>>>>>>>>>>
>>>>>>>>>> What am I missing?
>>>>>>>>>>
>>>>>>>>>> As far as I understand, the .error message /must/ be "-quoted.
>>>>>>>>>
>>>>>>>>> Indeed. But AVR is one of the few targets which enable this extra
>>>>>>>>> warning. Why that is or whether it could be changed requires AVR
>>>>>>>>> knowledge, which I don#t have. There's also a surprising set of
>>>>>>>>> characters for which the warning would never appear. I don't know
>>>>>>>>> the history of that set, but it feels pretty arbitrary.
>>>>>>>>
>>>>>>>> Okay, I didn't even notice that it's target specific... The only
>>>>>>>> related place I could find is in gas/config/tc-avr.h:
>>>>>>>>
>>>>>>>> /* If you define this macro, GAS will warn about the use of
>>>>>>>>        nonstandard escape sequences in a string.  */
>>>>>>>> #define ONLY_STANDARD_ESCAPES
>>>>>>>
>>>>>>> This is it, yes.
>>>>>>>
>>>>>>>> Though whatever the behavior wrt. fishy escapes is, resolution
>>>>>>>> of macro arguments should run prior to that, no?
>>>>>>>
>>>>>>> No. Macros are processed after the scrubber (aka "pre-processor") has
>>>>>>> done its work.
>>>>>>
>>>>>> Whatever the technical limitations are; such a warning makes just no sense.
>>>>>
>>>>> The person who had added it likely was of a different opinion. I'm pretty sure
>>>>> things can be improved, and feel free to send a patch, but justifying such a
>>>>> change will likely require some archeology, not just saying "makes no sense".
>>>>
>>>> What I am trying to say is that warning for an unrecognized escape
>>>> sequence isn't very helpful when the sequence is NOT an escape sequence
>>>> to begin with.  In the example, \data is treated as a .macro parameter,
>>>> so there is no unknown escape sequence `\d' anywhere.
>>>
>>> The scrubber can't know this is a macro parameter reference.
>>
>> I understand that the artifact is due to some gas internals finesse.
>>
>> But that doesn't help the user's experience in any way.
> 
> Well, yes, but see below - we need a concrete proposal for how to change
> that.
> 
>> And it's still fine to warn for unrecognized escapes when there /are/
>> unrecognized escapes, so the tc-avr.h choice makes sense IMHO.
> 
> And how do you suggest the scrubber distinguish
> 
> 	.error "value \data is negative"
> 
> used in a macro from this used outside (or even inside, but with "data"
> not being a macro parameter)?

Wearing a user's hat:

1) A string is a string.

Just like in C, a string should be a string.  And that's actually
what the docs say on \:

| \ anything-else
|     Any other character when escaped by \ gives a warning, but
|     assembles as if the ‘\’ was not present. The idea is that if
|     you used an escape sequence you clearly didn’t want the literal
|     interpretation of the following character. However as has no
|     other interpretation, so as knows it is giving you the wrong
|     code and warns you of the fact.

https://sourceware.org/binutils/docs/as/Strings.html

That is, your

 > .error "value \data is negative"

should issue a warning and print "value data is negative".

CPP doesn't touch string literals in macro resolution, so when you
want a macro argument as (a part of) a string, then you have to
stringify it with #.  As far as I know, there is nothing like
stringification in .macro.  Assuming that a char like ^ works
on all platforms (or is provided by, say, tc-<target>.h),
making \data as a part of a string would then be:

.error "value "^\data" is negative"

This would resolve any ambiguities, and it would follow
GAS's own documentation.

Unfortunately, even though .macro nowhere says that param
resolution applies within strings, it mentions

| .print "\bar \baz"

in a .macro.  To make things even worse, " may have semantics that
don't don't means sting delimitation, like in

| .macro  sum from=0, to=5
|     .long  \from
|     .if    \to-\from
|         sum "(\from+1)",\to
|     .endif
| .endm


| [...] individual arguments will need to be enclosed in [...] double
| quote " characters. The latter may be the only viable option in
| certain situations, as only double quotes are actually stripped while
| establishing arguments.

And it would require that concatenating strings did work.  While

|  .string "con""cat"

works outside .macro, it throws an error within .macro.

So this is all a bit of a mess, and I don't see a way to resolve it.
Lest alone considering compatibility with previous versions of Binutils.

Johann

> Just to mention, there more anomalies here - at least:
> - For perhaps a small set of targets: While the "quotechar" static variable
>    allows for string quotation by other than '"', the case labels
>    circumventing the warning only (and potentially wrongly) cover '"'.
> - Only octal digits (and lower case 'f' and 'b') are excluded.
> To me the only viable solution looks to be to drop that warning altogether;
> this would then limit reporting to next_char_of_string(). Yet then there
> must have been a reason that it was added. And more targets than just AVR
> would be affected. (I'll see about doing the necessary archeology. Which
> may lead to nothing. In the meantime, could you add a respective entry to
> our bugzilla?)
> 
> Jan



More information about the Binutils mailing list