Bug 52554

Summary: Variable called $1 causes invalid asm to be generated
Product: gcc Reporter: Lukas Mai <rwxr-xr-x>
Component: targetAssignee: Not yet assigned to anyone <unassigned>
Status: RESOLVED DUPLICATE    
Severity: minor CC: cw, fw, jsm28
Priority: P3 Keywords: assemble-failure
Version: 4.6.3   
Target Milestone: ---   
See Also: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=46163
Host: Target: i686-pc-linux-gnu
Build: Known to work:
Known to fail: Last reconfirmed:

Description Lukas Mai 2012-03-10 21:28:49 UTC
The following code is somewhat silly, but gcc should either compile it correctly or print an error message, not generate invalid asm.

Here's my code:

int $1 = -1;

int main(void) {
	$1++;
	return $1;
}

Here's my command:

% gcc try.c
/tmp/ccVyjhob.s: Assembler messages:
/tmp/ccVyjhob.s:22: Error: operand type mismatch for `mov'

Here's my asm:

	.file	"try.c"
	.globl	$1
	.data
	.align 4
	.type	$1, @object
	.size	$1, 4
$1:
	.long	-1
	.text
	.globl	main
	.type	main, @function
main:
.LFB0:
	.cfi_startproc
	pushl	%ebp
	.cfi_def_cfa_offset 8
	.cfi_offset 5, -8
	movl	%esp, %ebp
	.cfi_def_cfa_register 5
	movl	$1, %eax
	incl	%eax
	movl	%eax, $1
	movl	$1, %eax
	popl	%ebp
	.cfi_def_cfa 4, 4
	.cfi_restore 5
	ret
	.cfi_endproc
.LFE0:
	.size	main, .-main
	.ident	"GCC: (GNU) 4.6.3"
	.section	.note.GNU-stack,"",@progbits

Here's my specs:

% gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/home/mauke/usr/local/libexec/gcc/i686-pc-linux-gnu/4.6.3/lto-wrapper
Target: i686-pc-linux-gnu
Configured with: ../gcc-4.6.3/configure --prefix=/home/mauke/usr/local --with-arch=native --with-tune=native --enable-__cxa_atexit --disable-nls --enable-languages=c,c++,go
Thread model: posix
gcc version 4.6.3 (GCC)
Comment 1 Richard Biener 2012-03-12 13:28:05 UTC
C does not allow an identifier to start with a dollar.  But we even accept
the program with -std=c99 -pedantic-errors.
Comment 2 Andreas Schwab 2012-03-12 14:22:00 UTC
6.4.2.1 says that an identifier may contain "other implementation-defined characters".
Comment 3 Lukas Mai 2012-03-13 16:57:38 UTC
It gets better:

int $42 = 0;

int main(void) {
    return $42;
}

% gcc try.c; ./a.out; echo $?      
42

% gcc -O2 try.c; ./a.out; echo $?   
42

% gcc -flto try.c; ./a.out; echo $?
/tmp/cc5Gwdzb.s: Assembler messages:
/tmp/cc5Gwdzb.s:13: Error: junk `.1988' after expression
lto-wrapper: gcc returned 1 exit status
/usr/bin/ld: lto-wrapper failed
collect2: ld returned 1 exit status
zsh: no such file or directory: ./a.out
127

% gcc -O -flto try.c; ./a.out; echo $?
0

So compiling this program either
1) generates bogus code,
2) causes assembler syntax errors, or
3) compiles correctly,
depending on which compiler flags are used.
Comment 4 Florian Weimer 2012-03-28 05:38:56 UTC
Some platforms (such as VMS) support $ in identifiers, similar to _.  It seems that your assembler doesn't:

http://gcc.gnu.org/onlinedocs/gcc/Dollar-Signs.html

(If you compile with -pedantic, you'll get a warning.)

This is not much different from platforms where global symbols are case-insensitive or severely limited in length.
Comment 5 openhardware 2012-03-28 09:36:47 UTC
Hi, I tested the 42 it mit older gcc, and it behaved better:

 gcc --version
gcc (GCC) 4.2.4 (Gentoo 4.2.4 p1.0)
Copyright (C) 2007 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.


 cat >try.c
int $42 = 0;

int main(void) {
    return $42;
}


 gcc try.c; ./a.out; echo $?  
/tmp/ccY61UFa.s: Assembler messages:
/tmp/ccY61UFa.s:18: Error: junk `(%rip)' after expression
bash: ./a.out: No such file or directory
127

 gcc -O2 try.c; ./a.out; echo $? 
/tmp/ccXk0zWe.s: Assembler messages:
/tmp/ccXk0zWe.s:8: Error: junk `(%rip)' after expression
bash: ./a.out: No such file or directory
127


But I would expect an syntax error thrown by gcc here.
Comment 6 Lukas Mai 2012-03-29 11:26:12 UTC
From the gcc documentation:

| However, dollar signs in identifiers are not supported on a few target
| machines, typically because the target assembler does not allow them.

That's nice, but:

|   * If the compiler produces invalid assembly code, for any input
|     whatever (except an `asm' statement), that is a compiler bug,
|     unless the compiler reports errors (not just warnings) which would
|     ordinarily prevent the assembler from being run.

|   * If the compiler produces valid assembly code that does not
|     correctly execute the input source code, that is a compiler bug.

If my target assembler (gas) doesn't allow them, you must produce an error. Making up asm syntax and handing it to the assembler is not an option.

Alternatively, change the documentation to the effect that invalid assembly code and valid (but semantically wrong) assembly code aren't necessarily compiler bugs.
Comment 7 openhardware 2012-03-29 13:40:14 UTC
"Alternatively, change the documentation to the effect that invalid assembly
code and valid (but semantically wrong) assembly code aren't necessarily
compiler bugs."

Its a "windows-approach"
Not a bug but a feature.

Intel calls their errata sheets for silicon bugs "specification update"
That's really sweet, so whats a spec for?

Please fix it in gcc to be a syntax error, or at least throw a warning like
"Illegal variable name found in line # might cause illegal assembly code and thus unpredictable results!".

This would be the best, so if one has a special "geeks-assembler", 
that allows a $ to be send to the assembler, so one could use it, for what special geeks-reason ever (may be, to have a hack to illegally allign a variable in memory  between the rails of the processors word length in order to smear it into two registers [highbyte of lower register and lowbyte of upper register] of some IO or to do some other dirty stuff directly from hell)
Comment 8 Lukas Mai 2012-04-04 03:37:48 UTC
According to the documentation this is a valid bug. See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52554#c6.
Comment 9 Andrew Pinski 2021-07-29 23:46:18 UTC
Dup of bug 31782.

*** This bug has been marked as a duplicate of bug 31782 ***