Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Evaluation of pointer #52

Open
MorelSerge opened this issue Mar 14, 2019 · 4 comments
Open

Evaluation of pointer #52

MorelSerge opened this issue Mar 14, 2019 · 4 comments

Comments

@MorelSerge
Copy link

MorelSerge commented Mar 14, 2019

I'm stumbling on a weird error. I got an array of structs like this:

typedef struct triple_pattern {
  uint8_t subject[MAX_TP_OBJ_LENGTH];
  uint8_t predicate[MAX_TP_OBJ_LENGTH];
  uint8_t object[MAX_TP_OBJ_LENGTH];
} triple_pattern_t;
triple_pattern_t triple_patterns[MAX_TP];
uint8_t c_tp_part[MAX_TP_OBJ_LENGTH];

Now I have a separate state variable int state_a, which I then use to access triple_patterns like this:

if (state_a < MAX_TP) {
  triple_patterns[state_a].subject = c_tp_part;
}

This does not work, see stacktrace below.
What does work is this:

int j;
for (j = 0; j < MAX_TP; j++) {
  if (j == state_a) {
    triple_patterns[j].subject = c_tp_part;
  }
}

What am I missing in the first example that makes it fail to compile?

Thanks

Stacktrace:

Expanding circuit to file compute.c.ZAATAR.circuit
Exception in thread "main" java.lang.RuntimeException: I don't know how to evaluate the value of the pointer.
at SFE.Compiler.Operators.PointerAccessOperator.evaluatePossibleValues(PointerAccessOperator.java:330)
at SFE.Compiler.Operators.PointerAccessOperator.evaluatePossibleValues(PointerAccessOperator.java:305)
at SFE.Compiler.Operators.PointerAccessOperator.evaluatePossibleValues(PointerAccessOperator.java:315)
at SFE.Compiler.Operators.PointerAccessOperator.asAddressInternal(PointerAccessOperator.java:229)
at SFE.Compiler.Operators.PointerAccessOperator.asAddressInternal(PointerAccessOperator.java:240)
at SFE.Compiler.Operators.PointerAccessOperator.asAddress(PointerAccessOperator.java:141)
at SFE.Compiler.ProtoAssignmentStatement.toAssignmentStatements(ProtoAssignmentStatement.java:75)
at ccomp.parser_hw.CCompiler.addStatement(CCompiler.java:521)
at ccomp.parser_hw.CCompiler.getExpr(CCompiler.java:997)
at ccomp.parser_hw.CCompiler.getExpr(CCompiler.java:793)
at ccomp.parser_hw.CCompiler.expandStatement(CCompiler.java:660)
at ccomp.parser_hw.CCompiler.expandStatement(CCompiler.java:635)
at ccomp.parser_hw.CCompiler.getExpr(CCompiler.java:851)
at ccomp.parser_hw.CCompiler.expandStatement(CCompiler.java:660)
at ccomp.parser_hw.CCompiler.expandStatement(CCompiler.java:635)
at ccomp.parser_hw.CCompiler.getExpr(CCompiler.java:851)
at ccomp.parser_hw.CCompiler.expandStatement(CCompiler.java:660)
at ccomp.parser_hw.CCompiler.expandStatement(CCompiler.java:635)
at ccomp.parser_hw.CCompiler.getExpr(CCompiler.java:873)
at ccomp.parser_hw.CCompiler.expandStatement(CCompiler.java:660)
at ccomp.parser_hw.CCompiler.expandStatement(CCompiler.java:635)
at ccomp.parser_hw.CCompiler.getExpr(CCompiler.java:873)
at ccomp.parser_hw.CCompiler.expandStatement(CCompiler.java:660)
at ccomp.parser_hw.CCompiler.expandStatement(CCompiler.java:635)
at ccomp.parser_hw.CCompiler.getExpr(CCompiler.java:873)
at ccomp.parser_hw.CCompiler.expandStatement(CCompiler.java:660)
at ccomp.parser_hw.CCompiler.expandStatement(CCompiler.java:635)
at ccomp.parser_hw.CCompiler.getExpr(CCompiler.java:851)
at ccomp.parser_hw.CCompiler.expandStatement(CCompiler.java:660)
at ccomp.parser_hw.CCompiler.expandStatement(CCompiler.java:635)
at ccomp.parser_hw.CCompiler.getExpr(CCompiler.java:851)
at ccomp.parser_hw.CCompiler.expandStatement(CCompiler.java:660)
at ccomp.parser_hw.CCompiler.expandStatement(CCompiler.java:635)
at ccomp.parser_hw.CCompiler.expandStatement(CCompiler.java:635)
at ccomp.parser_hw.CCompiler.expandStatement(CCompiler.java:695)
at ccomp.parser_hw.CCompiler.expandStatement(CCompiler.java:635)
at ccomp.parser_hw.CCompiler.genericFunctionCall(CCompiler.java:1050)
at ccomp.parser_hw.CCompiler.getExpr(CCompiler.java:958)
at ccomp.parser_hw.CCompiler.getExpr(CCompiler.java:793)
at ccomp.parser_hw.CCompiler.getExpr(CCompiler.java:814)
at ccomp.parser_hw.CCompiler.expandStatement(CCompiler.java:660)
at ccomp.parser_hw.CCompiler.expandStatement(CCompiler.java:635)
at ccomp.parser_hw.CCompiler.access$1100(CCompiler.java:114)
at ccomp.parser_hw.CCompiler$CMainStatement.toAssignmentStatements(CCompiler.java:491)
at SFE.Compiler.BlockStatement.toAssignmentStatements(BlockStatement.java:111)
at SFE.Compiler.FunctionBody.toAssignmentStatements(FunctionBody.java:31)
at zcc.ZCC.compile(ZCC.java:260)
at zcc.ZCC.main(ZCC.java:127)
Makefile:113: recipe for target 'bin/compute.params' failed
make: *** [bin/compute.params] Error 1

@maxhowald
Copy link
Contributor

Thanks for the report! Do you have a minimal example that throws the error? I couldn't seem to reproduce it with just the just your snippet, using the code below (with inputs and outputs to ensure the whole computation isn't optimized to nothing...):

#include <stdint.h>

#define MAX_TP_OBJ_LENGTH 5
#define MAX_TP 5

typedef struct triple_pattern {
	uint8_t subject[MAX_TP_OBJ_LENGTH];
	uint8_t predicate[MAX_TP_OBJ_LENGTH];
	uint8_t object[MAX_TP_OBJ_LENGTH];
} triple_pattern_t;
triple_pattern_t triple_patterns[MAX_TP];
uint8_t c_tp_part[MAX_TP_OBJ_LENGTH];

struct In {
	int a;
};

struct Out {
	int b;
};

int compute(struct In *input, struct Out *output) {
	int j;
	for (j = 0; j < MAX_TP_OBJ_LENGTH; j++) {
		c_tp_part[j] = input->a;
	}

	int state_a = input->a;

	if (state_a < MAX_TP) {
		triple_patterns[state_a].subject = c_tp_part;
		output->b = triple_patterns[state_a].subject[0];
	}
}

@MorelSerge
Copy link
Author

MorelSerge commented Mar 15, 2019

Hi, thanks for getting back to me!
I reduced my code to the least amount possible that produces the same error:

Compute.c

#include <stdint.h>
#include "compute.h"

int compute(In_t *input, Out_t *output) {
  output_t objects[MAX_TP];
  extract(input->input, objects);
}

int extract(uint8_t input[MAX_INPUT], output_t objects[MAX_TP]) {
  int i, j, k;
  uint8_t c_char;
  uint8_t c_tp_part[MAX_TP_OBJ_LENGTH];

  k = 0;
  j = 0;
  for (i = 0; i < MAX_INPUT; i++) {
    c_char = input[i];
    if (c_char != UNDEFINED) {
      if (j == 0) {
        j = 1;
      } else {
        if (k == 0 && j - 1 < MAX_TP) {
          objects[j - 1].a = c_tp_part;
        }
      }
    }
  }
  return 1;
}

Compute.h

#define MAX_INPUT 500
#define MAX_RESULTS 10
#define MAX_TP_OBJ_LENGTH 10
#define MAX_TP_LENGTH  3 * MAX_TP_OBJ_LENGTH + 3
#define MAX_TP 3
#ifndef UNDEFINED
  #define UNDEFINED 0
#endif

typedef struct In {
	uint8_t input[MAX_INPUT];
} In_t;

typedef struct output {
  uint8_t a[MAX_TP_OBJ_LENGTH];
  uint8_t b[MAX_TP_OBJ_LENGTH];
  uint8_t c[MAX_TP_OBJ_LENGTH];
} output_t;

typedef struct Out {
  output_t results[MAX_RESULTS];
} Out_t;

Can you reproduce the exception with this?

@maxhowald
Copy link
Contributor

I was able to reproduce the error you got, thanks.

It looks like this is a bug in the way that the compiler handles passing arrays of structs with array members to functions. I'll try to look into this a bit more deeply and get back to you, but as a workaround, you could try moving the declaration to a global variable.

For example, the following compiles without error:

#include <stdint.h>
#include "compute.h"

output_t objects[MAX_RESULTS];
int compute(In_t *input, Out_t *output) {
  extract(input->input);
  output->results = objects;
}

int extract(uint8_t input[MAX_INPUT]) {
  int i, j, k;
  uint8_t c_char;
  uint8_t c_tp_part[MAX_TP_OBJ_LENGTH];

  k = 0;
  j = 0;
  for (i = 0; i < MAX_INPUT; i++) {
    c_char = input[i];
    if (c_char != UNDEFINED) {
      if (j == 0) {
        j = 1;
      } else {
        if (k == 0 && j - 1 < MAX_TP) {
          objects[j - 1].a = c_tp_part;
        }
      }
    }
  }
  return 1;
}

@MorelSerge
Copy link
Author

This does compile successfully! Thank you.

One thing that might help you find the bug is that even removing 1 "if" statement in the code I previously posted, makes it work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants