Source: aspectc++
Version: 1:1.2+svn20150823-1
Tags: patch

It failed to build on arm64 and some other architectures:

https://buildd.debian.org/status/package.php?p=aspectc%2B%2B&suite=sid

Those are architectures with plain char unsigned, I presume.

The error was:

/build/aspectc++-Rtfj1g/aspectc++-1.2+svn20150823/Puma.copy/gen-release/step1/src/PreExprParser.cc:1797:
 error: `YYMINORTYPE' has no member named `yy'

The cause seems to be a signed overflow in lemon.c:

  char *stddt;
  int hash;
  ...

    hash = 0;
    for(j=0; stddt[j]; j++){
      hash = hash*53 + stddt[j];
    }
    if( hash<0 ) hash = -hash;
    hash = hash%arraysize;

If char is unsigned then the compiler deduces that hash will never be
negative (because a signed overflow would be illegal) and deletes the
if statement. But then at run time hash mysteriously is negative, in
about 50% of cases, unless the strings are very short, and then code
gets generated that contains "yy-19" instead of "yy27", or whatever.

To fix it, it would be enough to make "hash" an unsigned int, I think.
The attached patch goes a bit further and tries to make the hash
computation give the same result on any system, which may or may not
be a useful feature.
diff -ru aspectc++-1.2+svn20150823.orig/Puma/tools/lemon/lemon.c aspectc++-1.2+svn20150823/Puma/tools/lemon/lemon.c
--- aspectc++-1.2+svn20150823.orig/Puma/tools/lemon/lemon.c
+++ aspectc++-1.2+svn20150823/Puma/tools/lemon/lemon.c
@@ -2845,7 +2845,7 @@
   int maxdtlength;          /* Maximum length of any ".datatype" field. */
   char *stddt;              /* Standardized name for a datatype */
   int i,j;                  /* Loop counters */
-  int hash;                 /* For hashing the name of a type */
+  unsigned long hash;       /* For hashing the name of a type */
   char *name;               /* Name of the parser */
 
   /* Allocate and initialize types[] and allocate stddt[] */
@@ -2889,9 +2889,8 @@
     stddt[j] = 0;
     hash = 0;
     for(j=0; stddt[j]; j++){
-      hash = hash*53 + stddt[j];
+      hash = (hash*53 + (unsigned char)stddt[j]) & 0xffffffff;
     }
-    if( hash<0 ) hash = -hash;
     hash = hash%arraysize;
     while( types[hash] ){
       if( strcmp(types[hash],stddt)==0 ){

Reply via email to