#### #### This file is distributed under the MIT License. See LICENSE.md for details. #### -std=c11 # Assume we don't have a C-runtime on the target (to allow weird signature on # main, and to turn off warnings about mismatched c stdlib signatures). -ffreestanding # Prevent recompilation of decompiled C code to cause UB on overflows # It's equivalent to -fwrapv -fwrapv-pointer -fno-strict-overflow # Memory accesses via casted pointers are pretty common in decompiled code. -fno-strict-aliasing # Treat warnings as errors -Werror # Enable a lot of warnings -Wall -Wextra # Warnings that could be enabled in the future if we become better behaved, but # that we leave disabled for now. # -pedantic-errors # Disable a bunch of warning that we know we don't support yet. # # For every warning added to this list we an explanation on why it's needed must # be provided so that we can try and re-enable the warnings in the future. # All the types from the model are declared with __attribute__((packed)), which # means that taking the address of any field may result in an unaligned pointer # value. We just don't care about that, and we can't avoid that, so we are not # very likely to ever be able to re-enable this warning. -Wno-address-of-packed-member # Pointer arithmetic involving large but non-negative constant values triggers # this diagnostic. Ultimately there is no good way to ensure that decompiled # code does not contain such pointer arithmetic, so the warning is disabled. # # Expressions such as this `ptr + 0x3FFFFFFFFFFFFFCAUL` were encountered coming # from decompiled binaries, which caused this warning to be triggered. -Wno-array-bounds # This is usually emitted because MakeModelGEPPass builds two different # type-based traversal for two pointer expressions that are then compared, which # ends up with an expression in C that compares two distinct pointer types. # Unless MakeModelGEPPass becomes perfect and guarantees not to ever emit this # kind of situations, this warning can hardly be enabled. -Wno-compare-distinct-pointer-types # This happens when the second and third operands of a ternary in C have # different types. # Eventually we hope to be able to re-enable this warning, when we start # handling casts and implicit conversion in a robust way. -Wno-conditional-type-mismatch # This is usually emitted because MakeModelGEPPass builds two different # type-based traversal for two pointer expressions that are then compared, which # ends up with an expression in C that compares two distinct pointer types. # Unless MakeModelGEPPass becomes perfect and guarantees not to ever emit this # kind of situations, this warning can hardly be enabled. -Wno-incompatible-pointer-types # The following two are caused by the fact that we don't handle very cleanly # integer casts and pointer casts yet. # In principle we should be able to remove these when we handle casts properly, # but at the same time if we end up using implicit casts and conversions for # improving conciseness of decompiled code these may be impossible to ever # disable because they would warn against the implicit casts that we're # exploiting for concisensess. -Wno-int-conversion -Wno-int-to-pointer-cast # We end up dereferencing null pointers in a few situations due to various LLVM # optimizations that propagate undef, freeze, or poison values. # In principle we should investigate all these occurrences carefully because # they are situations where LLVM's optimizations could be breaking semantics. # We should try to fix this and re-enable this warning to guard against other # such cases in the future. -Wno-null-dereference # TODO: This is caused by some missing parentheses causing weird order of # evaluation. In principle this should already be handled by # OperatorPrecedenceResolutionPass, but apparently there are still a few cases # that should be investigated before re-enabling this warning. -Wno-parentheses # This happens because we end up comparing a pointer-typed value with the 0 # constant instead of NULL. # We should be able to fix this by emitting NULL directly and re-enable this # warning. -Wno-pointer-integer-compare # This happens in situations like: `uint8_t *string = "some_string". # The compiler complains because we're assigning a pointer to the unique plain # `char` type to a variable whose type is `uint8_t`, and `char` and `uint8_t` # have mismatched signedness. # It's very unlikely that we will be able to re-enable this warning. -Wno-pointer-sign # The following happens when we assign a pointer-typed value to an integer # value. In principle this is worth trying to improve, since it represents an # opportunity for our type-inference to be better in inferring the type of the # variable, which should also be a pointer. # However, given that at some point we plan to exploit C implicit casts and # conversions to make the decompiled code more concise, we might end up in a # situation where we're actively exploiting this and we cannot re-enable the # warning because it would just warn about the implicit cast we're exploiting to # make the C code less verbose. -Wno-pointer-to-int-cast # This is typically triggered when a function that returns non-void does not # return a value in all control paths. # This is typically due to function F1 calling F2 who is noreturn. The problem # is that F2 may be properly detected as noreturn in the model, but it doesn't # have an __attribute__((noreturn)) when decompiled to C, which causes the # warning. -Wno-return-type # For some reason we end up comparing integers with different signedness. This # typically involves generic*_t, which is implicitly unsigned in C, but it's not # signed nor unsigned in the Model. # Hopefully when we really take care of implicit casts among integers in C we'll # be able to enable this warning again. # However, if we end up making purposeful use of implicit casts and conversion # in C to reduce verbosity of the decompiled code, we will never be able to # enable this warning again, because it would end up warning us about implicit # conversion that we are exploiting on purpose. -Wno-sign-compare # This just triggers a very big weird case as of today. We could think of # re-enabling this warning but we have to deal with that first. -Wno-tautological-constant-out-of-range-compare # We happen to have uninitialized local variable that are used before being # written. They are leftover and should go away, but for now they are still # common, so this warning should be disabled. -Wno-uninitialized # This typically happens in the following 2 scenarios. # 1) Some LLVM's optimization cuts away some piece of the CFG, because it # recognizes it as dead code, so the variable is left set but never used, # because it was only used in the dead removed part. # 2) We initialize the variable with the return value of a call instruction, but # then the variable is never used again. This is due to some quirks of how # variables associated with function calls are created. # # Both cases should be handled correctly, so eventually we should be able to # re-enable this warning. -Wno-unused-but-set-variable # 1) An argument that is present in the model on the function prototype is # effectively not used in the binary. This may be caused by misdetection of # function arguments by revng, or by a user setting the model with a # prototype with an erroneous additional argument. # 2) Identification of function boundaries and/or control flow is wrong, leading # to a situation where the lifted function's body is truncated via # llvm.unreachable. Truncation of the body may render the arguments unused, # if they were used in the part of the body that gets removed. -Wno-unused-but-set-parameter # The following is typically emitted for typedefs of local stack types for # functions that end up not using the stack. -Wno-unused-local-typedefs # This happens if the argument of a function as specified in the prototype is # never used, which may be caused by a bug in argument detection but may also be # a legit unused argument, or even the consequence of a user-provided function # prototype. # We don't expect to be able to enable this warning, unless we inspect the body # of the function when printing the prototype and omit the names of the unused # parameters. -Wno-unused-parameter # The following two tend to be emitted when some optimizations remove some # branches that are considered dead. # For now we have disabled them because they happen quite often, but we should # really look into this and figure out if something is wrong in the lifting # process or in the optimizations we do, because this should not really happen. -Wno-unused-value -Wno-unused-variable # The following is emitted when an isolated function is detected as noreturn by # revng (and the _Noreturn attribute is hence emitted in the decompiled C code), # but the body of the function actually calls another dynamic function that is # not marked noreturn. # Typically this happens for wrappers to __libc_start_main. # We might think of fixing this by just manually curating a list of functions # that should be noreturn, but this is error-prone. # Also, for instance, the __libc_start_main function does not have the noreturn # attribute in the libc, so strictly speaking it would even be wrong to mark it # noreturn. -Wno-invalid-noreturn # The following is emitted when in revng we emit a condition in the form: # ``` # if (&var_0->_offset_1) # ``` # The compiler warns because taking a non-null address as a boolean always # returns true. # On the one hand, this is still valid C, and coming from assembly it may be # possible. # On the other hand, a sane compiler would have optimized that away when # producing the binary, so this pattern may be a hint that we're doing something # wrong in revng. # For now we have blindly disabled it because in our arm tests it currently # happens and it's not high priority at the moment of this writing. # In the future it might make sense to turn it on again, and properly # investigate when it happens in our test, to figure out if we're actually # breaking semantics in some subtle way in some cases. -Wno-pointer-bool-conversion # TODO: this warning is disabled because at the moment it triggers in situations # where the self-assignments are not bugs, but simply sub-optimal C code # generation. As soon as the sub-optimal code generation is resolved, this # warning should be re-enabled. # # The suboptimal code generation is due to various situation where LLVM passes # that emit local variables (allocas) before conversion to clift, e.g. STS and # ExitSSA (but more are planned in the future). # Because these passes both generate local variables at different times, but # they don't know about each other (and their order could even be swapped in the # future), the only way to fix this sub-optimal C code generation is to unify # all these passes in a general framework, where there are multiple analyses (in # the LLVM sense) that pick instructions for serialization for various reasons. # All the results for these analyses must be integrated in by a single # transformation pass, that only emits local variables once, yielding a result # where redundant self-assignments never occur. # We already have plans for implementing this, and when that will be done, we # will be able to silence this warning again. -Wno-self-assign