GithubHelp home page GithubHelp logo

cznic / cc Goto Github PK

View Code? Open in Web Editor NEW
165.0 165.0 20.0 14.29 MB

github.com/cznic/cc has moved to modernc.org/cc

Home Page: https://godoc.org/modernc.org/cc

License: BSD 3-Clause "New" or "Revised" License

Makefile 0.07% Go 2.72% Yacc 0.87% Lex 0.06% C 92.45% C++ 1.51% Logos 0.05% Roff 0.01% Objective-C 0.01% Tcl 2.21% Shell 0.02% Assembly 0.03%

cc's People

Contributors

ctrlzvi avatar cznic avatar kortschak avatar mattn avatar myitcv avatar pwaller avatar steffengy avatar xlab avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cc's Issues

Typed defines are not supported.

typedef unsigned long PaStreamCallbackFlags;

#define paInputUnderflow   ((PaStreamCallbackFlags) 0x00000001)

The paInputUnderflow macro gets nil Value in macro map (map[int]*cc.Macro).

Digging into:

    macro.Value, macro.Type = p.lx.parsePPConstExpr0(rl, p)

...leads to the sloppy slope in the code :)

for i, tok := range l.toks {
        if tok.Rune == IDENTIFIER {
            if p.macros.m[tok.Val] != nil {
                l.report.ErrTok(tok, "expected constant expression")
                return nil, nil
            }

            tok.Rune = INTCONST
            tok.Val = id0
            l.toks[i] = tok
        }
    }

Which can't handle typecasts and parens well, so yyParse gets confused on extra parens:

    l.state = lsConstExpr0
    if err := yyParse(l); err == 0 {
        e := l.constantExpression
        return e.Value, e.Type
    } else {
        // butt hurt!
        log.Println("bad parse:", l.toks)
    }

Assignment to union type fail

typedef union{int foo; double bar} u;

void f(u) {}

void g() {
        int i;
        f(i);
}

is valid C, but the type checker rejects it.

Macro token pasting: L ## 'x' should produce a long char const.

Now it produces an identifier, because the left argument of ##, if present, always determines the resulting token type. In this case the resulting token type is neither the type of the arguments. This behavior is not mentioned in the specification but it's the only one making sense. The same applies to long string constants.

FunctionDefinition parameter scope wrong.

Complex function defintions like eg.

// Declare f as function (char) returning pointer to function (int) returning long.
//
// http://cdecl.ridiculousfish.com/?q=long+%28*f%28char%29%29+%28int%29%3B
//
long (*f(char c))(int i) { char d = c; }

will fail with c undefined.

The latest 3 commits that need to be incorporated somehow.

Hi, please review commits b58b670, 0aefe3d and 37d1391 in the cgogen branch. These are only changes I made to keep things running, so finishing them off will mean a full sync with upstream master of the CC, that'd be a very happy moment for me.

So, the patch regarding TypeSpecifier() *TypeSpecifier allows me to walk enums and get their members, since there is no native support of enums in Type yet.

Then, there is no implemented sizeOf / alignOf / structAlignOf for enums, so I added a few methods to walk enum and get the top type (because it could upgrade from uint32 up to int64). And use its values according to the model. This is very naive and may not work as per C specs, just for a consideration and as a temporary solution.

Both commits above are not for merging!

But the latest one is about a missing case in MustConvert, it gets triggered in cases like:

#define ABC 1000.0f

That seems to be all.

An uint64 case is missing for the '%' expression.

panic: internal error: uint64

goroutine 1 [running]:
panic(0x3636a0, 0xc820475170)
    /usr/local/go/src/runtime/panic.go:464 +0x3e6
github.com/cznic/cc.(*Expression).eval(0xc82098c540, 0xc8203563c0, 0x0, 0x0, 0x0, 0x0)
    /Users/xlab/Documents/dev/go/src/github.com/cznic/cc/ast2.go:798 +0x56b3
github.com/cznic/cc.(*ExpressionList).eval(0xc820622730, 0xc8203563c0, 0x0, 0x0, 0x0, 0x0)
    /Users/xlab/Documents/dev/go/src/github.com/cznic/cc/ast2.go:1457 +0x9d

Macro rescan incorrect

6.10.3.4 Rescanning and further replacement

  • 1 After all parameters in the replacement list have been substituted and # and ##
    processing has taken place, all placemarker preprocessing tokens are removed. Then, the
    resulting preprocessing token sequence is rescanned, along with all subsequent
    preprocessing tokens of the source file, for more macro names to replace.
  • 2 If the name of the macro being replaced is found during this scan of the replacement list
    (not including the rest of the source file’s preprocessing tokens), it is not replaced.
    ...

Currently sanitize, ie. checking for recursive macros, is performed during argument expansion, not "After all parameters in the replacement list have been substituted and # and ##
processing has taken place
". This causes expansion of NLMSG_ALIGN from <netlink.h>, in some older versions of it, to fail.

Unclosed ifdef causes panic in CC

Hi! It's not a bug, rather my typo that looks like this:

#ifdef __cplusplus
extern "C";

EOF

Not a big deal, but CC crashes with a weird panic that doesn't contribute to finding the root cause.

panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xb code=0x1 addr=0x10 pc=0x1ba214]

goroutine 18 [running]:
panic(0x3a8cc0, 0xc820010110)
    /usr/local/go/src/runtime/panic.go:481 +0x3e6
github.com/cznic/cc.(*pp).preprocessingFile(0xc82020a140, 0x0)
    /Users/xlab/Documents/dev/go/src/github.com/cznic/cc/cpp.go:982 +0x44
github.com/cznic/cc.Parse.func1(0xc820394120, 0xc82038c5a0, 0xc820390860, 0x68e520, 0xc820075770, 0xc820385ae0, 0xc820396200, 0xc820099780, 0x3, 0x4, ...)
    /Users/xlab/Documents/dev/go/src/github.com/cznic/cc/cc.go:472 +0x350
created by github.com/cznic/cc.Parse
    /Users/xlab/Documents/dev/go/src/github.com/cznic/cc/cc.go:474 +0xa47
make: *** [all] Error 2

unexpected '{'

Running debian linux, executing exactly the code you posted in maddyblue/moggio#50, I get this error:

/usr/include/x86_64-linux-gnu/bits/byteswap.h:46:1: unexpected '{', expected one of [',', ';', '=']

Here's the first part of that file. Line 46 is the first { in the file.

/* Macros to swap the order of bytes in integer values.
   Copyright (C) 1997-2015 Free Software Foundation, Inc.
   This file is part of the GNU C Library.

   The GNU C Library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   The GNU C Library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, see
   <http://www.gnu.org/licenses/>.  */

#if !defined _BYTESWAP_H && !defined _NETINET_IN_H && !defined _ENDIAN_H
# error "Never use <bits/byteswap.h> directly; include <byteswap.h> instead."
#endif

#ifndef _BITS_BYTESWAP_H
#define _BITS_BYTESWAP_H 1

#include <features.h>
#include <bits/types.h>
#include <bits/wordsize.h>

/* Swap bytes in 16 bit value.  */
#define __bswap_constant_16(x) \
     ((unsigned short int) ((((x) >> 8) & 0xff) | (((x) & 0xff) << 8)))

/* Get __bswap_16.  */
#include <bits/byteswap-16.h>

/* Swap bytes in 32 bit value.  */
#define __bswap_constant_32(x) \
     ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >>  8) |           \
      (((x) & 0x0000ff00) <<  8) | (((x) & 0x000000ff) << 24))

#ifdef __GNUC__
# if __GNUC_PREREQ (4, 3)
static __inline unsigned int
__bswap_32 (unsigned int __bsx)
{
  return __builtin_bswap32 (__bsx);
}
# elif __GNUC__ >= 2
#  if __WORDSIZE == 64 || (defined __i486__ || defined __pentium__        \
               || defined __pentiumpro__ || defined __pentium4__  \
               || defined __k8__ || defined __athlon__        \
               || defined __k6__ || defined __nocona__        \
               || defined __core2__ || defined __geode__          \
               || defined __amdfam10__)
/* To swap the bytes in a word the i486 processors and up provide the
   `bswap' opcode.  On i386 we have to use three instructions.  */
#   define __bswap_32(x) \
      (__extension__                                  \
       ({ unsigned int __v, __x = (x);                        \
      if (__builtin_constant_p (__x))                     \
        __v = __bswap_constant_32 (__x);                      \
      else                                    \
        __asm__ ("bswap %0" : "=r" (__v) : "0" (__x));            \
      __v; }))
#  else
#   define __bswap_32(x)                              \
      (__extension__                                  \
       ({ unsigned int __v, __x = (x);                        \
      if (__builtin_constant_p (__x))                     \
        __v = __bswap_constant_32 (__x);                      \
      else                                    \
        __asm__ ("rorw $8, %w0;"                          \
             "rorl $16, %0;"                          \
             "rorw $8, %w0"                       \
             : "=r" (__v)                         \
             : "0" (__x)                          \
             : "cc");                             \
      __v; }))
#  endif
# else
#  define __bswap_32(x) \
     (__extension__                               \
      ({ unsigned int __x = (x); __bswap_constant_32 (__x); }))
# endif
#else
static __inline unsigned int
__bswap_32 (unsigned int __bsx)
{
  return __bswap_constant_32 (__bsx);
}
#endif

HostConfig must respect cpp path overrides

I'm creating a ticket for the discussion we had by email. So the problem is that HostConfig aims for cpp and does not respect any overrides via CPP env variable for example.

func HostConfig(opts ...string) (predefined string, includePaths, sysIncludePaths []string, err error) {
    args := append(append([]string{"-dM"}, opts...), "/dev/null")
    pre, err := exec.Command("cpp", args...).Output()
    if err != nil {
        return "", nil, nil, err
    }
...

My suggestion is to do it like this:

cppPath := "cpp"
if path, ok := os.LookupEnv("CPP"); ok {
    cpPath = path
}
pre, err := exec.Command(cppPath, ...

Overflow in enumeration value: 4294967040

Having this enum:

enum {
    AINPUT_SOURCE_UNKNOWN = 0x00000000,
    AINPUT_SOURCE_ANY = 0xffffff00,
};

It seems that CC tries to handle 0xffffff00 as int32, you previously have said:

I've made enum types have always the properties of C int. The reason is that the C99 specification mandates that the enum const expression value must be representable as C int.

But from C99 §6.7.2.2/4:

Each enumerated type shall be compatible with char, a signed integer type, or an unsigned integer type. The choice of type is implementation-defined but shall be capable of representing the values of all the members of the enumeration.

So in this case it must be treated as uint32 and be represented with no issues.

A MustConvert case for unsigned long, ULong is missing.

panic: internal error unsigned long, ULong

goroutine 1 [running]:
panic(0x362fe0, 0xc82024f310)
    /usr/local/go/src/runtime/panic.go:464 +0x3e6
github.com/cznic/cc.(*Model).MustConvert(0x630b20, 0x2fa4e0, 0xc82024f2b4, 0x707a60, 0xc820482720, 0x0, 0x0)
    /Users/xlab/Documents/dev/go/src/github.com/cznic/cc/model.go:591 +0xa57
github.com/cznic/cc.(*Expression).eval(0xc8207a0c00, 0xc8203583c0, 0x0, 0x0, 0x0, 0x0)
    /Users/xlab/Documents/dev/go/src/github.com/cznic/cc/ast2.go:729 +0x38eb

Type.CanAssignTo must consider composite function types.

Example

void f(void(*)(int));
void g(int);

void h() {
        f((void(*)()g));
}

currently results in argument type check fail, but the specs permit this:

6.2.7, 3

  • If only one type is a function type with a parameter type list (a function prototype),
    the composite type is a function prototype with the parameter type list.

TestPreprocessor failure.

--- FAIL: TestPreprocessor (1.99s)
    all_test.go:558: 
        got testdata/dev/sqlite3/shell.c:4052:13: STRINGLITERAL "\"nArg<= (int)(sizeof( azArg )/sizeof( azArg [0]))\""
        exp /tmp/cc-test-311690362:8670:4: STRINGLITERAL "\"nArg<=(int)(sizeof(azArg)/sizeof(azArg[0]))\""
FAIL
exit status 1
FAIL    github.com/cznic/cc 2.026s

A binOpType case missing for ULong ULong.

panic: ULong ULong

goroutine 1 [running]:
panic(0x363840, 0xc820481260)
    /usr/local/go/src/runtime/panic.go:464 +0x3e6
github.com/cznic/cc.(*Model).binOpType(0x631b20, 0x708b28, 0xc82095e180, 0x708b28, 0xc820357680, 0x0, 0x0)
    /Users/xlab/Documents/dev/go/src/github.com/cznic/cc/model.go:1068 +0x486
github.com/cznic/cc.(*Model).binOp(0x631b20, 0xc8203543c0, 0x70d540, 0xc820958780, 0x70d540, 0xc820958a80, 0x0, 0x0, 0x0, 0x0, ...)
    /Users/xlab/Documents/dev/go/src/github.com/cznic/cc/model.go:892 +0x12e

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.